7 typedef struct image_s
{
8 int width
, height
, stride
;
9 unsigned char *buffer
; // RGB24
12 ASS_Library
*ass_library
;
13 ASS_Renderer
*ass_renderer
;
15 void msg_callback(int level
, const char *fmt
, va_list va
, void *data
)
24 static void write_png(char *fname
, image_t
*img
)
29 png_byte
**row_pointers
;
33 png_create_write_struct(PNG_LIBPNG_VER_STRING
, NULL
, NULL
, NULL
);
34 info_ptr
= png_create_info_struct(png_ptr
);
37 if (setjmp(png_ptr
->jmpbuf
)) {
38 png_destroy_write_struct(&png_ptr
, &info_ptr
);
43 fp
= fopen(fname
, "wb");
45 printf("PNG Error opening %s for writing!\n", fname
);
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
);
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
);
73 static void init(int frame_w
, int frame_h
)
75 ass_library
= ass_library_init();
77 printf("ass_library_init failed!\n");
81 ass_set_message_cb(ass_library
, msg_callback
, NULL
);
83 ass_renderer
= ass_renderer_init(ass_library
);
85 printf("ass_renderer_init failed!\n");
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
));
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;
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
)
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
);
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;
133 dst
+= frame
->stride
;
137 static void blend(image_t
* frame
, ASS_Image
*img
)
141 blend_single(frame
, img
);
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;
154 printf("usage: %s <image file> <subtitle file> <time>\n", argv
[0]);
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
);
164 printf("track init failed!\n");
169 ass_render_frame(ass_renderer
, track
, (int) (tm
* 1000), NULL
);
170 image_t
*frame
= gen_image(frame_w
, frame_h
);
173 ass_free_track(track
);
174 ass_renderer_done(ass_renderer
);
175 ass_library_done(ass_library
);
177 write_png(imgfile
, frame
);