12 int width, height, stride;
13 unsigned char* buffer; // RGB24
16 ass_library_t* ass_library;
17 ass_renderer_t* ass_renderer;
19 static void write_png(char *fname, image_t* img)
24 png_byte **row_pointers;
27 png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
28 info_ptr = png_create_info_struct(png_ptr);
31 if (setjmp(png_ptr->jmpbuf)) {
32 png_destroy_write_struct(&png_ptr, &info_ptr);
37 fp = fopen (fname, "wb");
39 printf("PNG Error opening %s for writing!\n", fname);
43 png_init_io(png_ptr, fp);
44 png_set_compression_level(png_ptr, 0);
46 png_set_IHDR(png_ptr, info_ptr, img->width, img->height,
47 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
48 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
50 png_write_info(png_ptr, info_ptr);
54 row_pointers = (png_byte **)malloc(img->height * sizeof(png_byte*));
55 for (k = 0; k < img->height; k++)
56 row_pointers[k] = img->buffer + img->stride * k;
58 png_write_image(png_ptr, row_pointers);
59 png_write_end(png_ptr, info_ptr);
60 png_destroy_write_struct(&png_ptr, &info_ptr);
67 static void init(int frame_w, int frame_h) {
68 ass_library = ass_library_init();
69 if (!ass_library) throw std::runtime_error("ass_library_init failed");
71 ass_set_fonts_dir(ass_library, "");
72 ass_set_extract_fonts(ass_library, 0);
73 ass_set_style_overrides(ass_library, NULL);
75 ass_renderer = ass_renderer_init(ass_library);
76 if (!ass_renderer) throw std::runtime_error("ass_renderer_init failed");
78 ass_set_frame_size(ass_renderer, frame_w, frame_h);
79 ass_set_margins(ass_renderer, 0, 0, 0, 0);
80 ass_set_use_margins(ass_renderer, 0);
81 ass_set_font_scale(ass_renderer, 1.);
82 ass_set_fonts(ass_renderer, NULL, "Sans", 1);
85 static image_t* gen_image(int width, int height) {
86 image_t* img = new image_t;
89 img->stride = width * 3;
90 img->buffer = (unsigned char*)calloc(1, height * width * 3);
91 for (int i = 0; i < height * width * 3; ++i)
92 img->buffer[i] = (i/3/50) % 100;
96 #define _r(c) ((c)>>24)
97 #define _g(c) (((c)>>16)&0xFF)
98 #define _b(c) (((c)>>8)&0xFF)
99 #define _a(c) ((c)&0xFF)
101 static void blend_single(image_t* frame, ass_image_t* img) {
102 unsigned char opacity = 255 - _a(img->color);
103 unsigned char r = _r(img->color);
104 unsigned char g = _g(img->color);
105 unsigned char b = _b(img->color);
111 dst = frame->buffer + img->dst_y * frame->stride + img->dst_x * 3;
112 for (int y = 0; y < img->h; ++y) {
113 for (int x = 0; x < img->w; ++x) {
114 unsigned k = ((unsigned)src[x]) * opacity / 255;
115 // possible endianness problems
116 dst[x*3] = (k*b + (255-k)*dst[x*3]) / 255;
117 dst[x*3+1] = (k*g + (255-k)*dst[x*3+1]) / 255;
118 dst[x*3+2] = (k*r + (255-k)*dst[x*3+2]) / 255;
121 dst += frame->stride;
125 static void blend(image_t* frame, ass_image_t* img) {
128 blend_single(frame, img);
132 printf("%d images blended\n", cnt);
135 int main(int argc, char* argv[]) {
136 const int frame_w = 640;
137 const int frame_h = 480;
140 printf("usage: %s <image file> <subtitle file> <time>\n", argv[0]);
143 char* imgfile = argv[1];
144 char* subfile = argv[2];
145 double tm = strtod(argv[3], 0);
147 init(frame_w, frame_h);
148 ass_track_t* track = ass_read_file(ass_library, subfile, NULL);
150 ass_image_t* img = ass_render_frame(ass_renderer, track, (int)(tm * 1000), NULL);
151 image_t* frame = gen_image(frame_w, frame_h);
153 write_png(imgfile, frame);