Support multiple faces per attachment correctly
[libass.git] / test / test.c
blobe2a88d16a50dafd5fdef03bd3a779c8e270b7af6
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <ass.h>
5 #include <png.h>
7 typedef struct image_s {
8 int width, height, stride;
9 unsigned char *buffer; // RGB24
10 } image_t;
12 ASS_Library *ass_library;
13 ASS_Renderer *ass_renderer;
15 void msg_callback(int level, const char *fmt, va_list va, void *data)
17 if (level > 6)
18 return;
19 printf("libass: ");
20 vprintf(fmt, va);
21 printf("\n");
24 static void write_png(char *fname, image_t *img)
26 FILE *fp;
27 png_structp png_ptr;
28 png_infop info_ptr;
29 png_byte **row_pointers;
30 int k;
32 png_ptr =
33 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
34 info_ptr = png_create_info_struct(png_ptr);
35 fp = NULL;
37 if (setjmp(png_ptr->jmpbuf)) {
38 png_destroy_write_struct(&png_ptr, &info_ptr);
39 fclose(fp);
40 return;
43 fp = fopen(fname, "wb");
44 if (fp == NULL) {
45 printf("PNG Error opening %s for writing!\n", fname);
46 return;
49 png_init_io(png_ptr, fp);
50 png_set_compression_level(png_ptr, 0);
52 png_set_IHDR(png_ptr, info_ptr, img->width, img->height,
53 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
54 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
56 png_write_info(png_ptr, info_ptr);
58 png_set_bgr(png_ptr);
60 row_pointers = (png_byte **) malloc(img->height * sizeof(png_byte *));
61 for (k = 0; k < img->height; k++)
62 row_pointers[k] = img->buffer + img->stride * k;
64 png_write_image(png_ptr, row_pointers);
65 png_write_end(png_ptr, info_ptr);
66 png_destroy_write_struct(&png_ptr, &info_ptr);
68 free(row_pointers);
70 fclose(fp);
73 static void init(int frame_w, int frame_h)
75 ass_library = ass_library_init();
76 if (!ass_library) {
77 printf("ass_library_init failed!\n");
78 exit(1);
81 ass_set_message_cb(ass_library, msg_callback, NULL);
83 ass_renderer = ass_renderer_init(ass_library);
84 if (!ass_renderer) {
85 printf("ass_renderer_init failed!\n");
86 exit(1);
89 ass_set_frame_size(ass_renderer, frame_w, frame_h);
90 ass_set_fonts(ass_renderer, NULL, "Sans", 1, NULL, 1);
93 static image_t *gen_image(int width, int height)
95 image_t *img = malloc(sizeof(image_t));
96 img->width = width;
97 img->height = height;
98 img->stride = width * 3;
99 img->buffer = (unsigned char *) calloc(1, height * width * 3);
100 memset(img->buffer, 63, img->stride * img->height);
101 //for (int i = 0; i < height * width * 3; ++i)
102 // img->buffer[i] = (i/3/50) % 100;
103 return img;
106 #define _r(c) ((c)>>24)
107 #define _g(c) (((c)>>16)&0xFF)
108 #define _b(c) (((c)>>8)&0xFF)
109 #define _a(c) ((c)&0xFF)
111 static void blend_single(image_t * frame, ASS_Image *img)
113 int x, y;
114 unsigned char opacity = 255 - _a(img->color);
115 unsigned char r = _r(img->color);
116 unsigned char g = _g(img->color);
117 unsigned char b = _b(img->color);
119 unsigned char *src;
120 unsigned char *dst;
122 src = img->bitmap;
123 dst = frame->buffer + img->dst_y * frame->stride + img->dst_x * 3;
124 for (y = 0; y < img->h; ++y) {
125 for (x = 0; x < img->w; ++x) {
126 unsigned k = ((unsigned) src[x]) * opacity / 255;
127 // possible endianness problems
128 dst[x * 3] = (k * b + (255 - k) * dst[x * 3]) / 255;
129 dst[x * 3 + 1] = (k * g + (255 - k) * dst[x * 3 + 1]) / 255;
130 dst[x * 3 + 2] = (k * r + (255 - k) * dst[x * 3 + 2]) / 255;
132 src += img->stride;
133 dst += frame->stride;
137 static void blend(image_t * frame, ASS_Image *img)
139 int cnt = 0;
140 while (img) {
141 blend_single(frame, img);
142 ++cnt;
143 img = img->next;
145 printf("%d images blended\n", cnt);
148 int main(int argc, char *argv[])
150 const int frame_w = 640;
151 const int frame_h = 480;
153 if (argc < 4) {
154 printf("usage: %s <image file> <subtitle file> <time>\n", argv[0]);
155 exit(1);
157 char *imgfile = argv[1];
158 char *subfile = argv[2];
159 double tm = strtod(argv[3], 0);
161 init(frame_w, frame_h);
162 ASS_Track *track = ass_read_file(ass_library, subfile, NULL);
163 if (!track) {
164 printf("track init failed!\n");
165 return 1;
168 ASS_Image *img =
169 ass_render_frame(ass_renderer, track, (int) (tm * 1000), NULL);
170 image_t *frame = gen_image(frame_w, frame_h);
171 blend(frame, img);
173 ass_free_track(track);
174 ass_renderer_done(ass_renderer);
175 ass_library_done(ass_library);
177 write_png(imgfile, frame);
179 return 0;