2 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
3 * Copyright (C) 2009 Grigori Goronzy <greg@geekmind.org>
5 * This file is part of libass.
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 typedef struct image_s
{
27 int width
, height
, stride
;
28 unsigned char *buffer
; // RGB24
31 ASS_Library
*ass_library
;
32 ASS_Renderer
*ass_renderer
;
34 void msg_callback(int level
, const char *fmt
, va_list va
, void *data
)
43 static void write_png(char *fname
, image_t
*img
)
48 png_byte
**row_pointers
;
52 png_create_write_struct(PNG_LIBPNG_VER_STRING
, NULL
, NULL
, NULL
);
53 info_ptr
= png_create_info_struct(png_ptr
);
56 if (setjmp(png_jmpbuf(png_ptr
))) {
57 png_destroy_write_struct(&png_ptr
, &info_ptr
);
62 fp
= fopen(fname
, "wb");
64 printf("PNG Error opening %s for writing!\n", fname
);
68 png_init_io(png_ptr
, fp
);
69 png_set_compression_level(png_ptr
, 0);
71 png_set_IHDR(png_ptr
, info_ptr
, img
->width
, img
->height
,
72 8, PNG_COLOR_TYPE_RGB
, PNG_INTERLACE_NONE
,
73 PNG_COMPRESSION_TYPE_DEFAULT
, PNG_FILTER_TYPE_DEFAULT
);
75 png_write_info(png_ptr
, info_ptr
);
79 row_pointers
= (png_byte
**) malloc(img
->height
* sizeof(png_byte
*));
80 for (k
= 0; k
< img
->height
; k
++)
81 row_pointers
[k
] = img
->buffer
+ img
->stride
* k
;
83 png_write_image(png_ptr
, row_pointers
);
84 png_write_end(png_ptr
, info_ptr
);
85 png_destroy_write_struct(&png_ptr
, &info_ptr
);
92 static void init(int frame_w
, int frame_h
)
94 ass_library
= ass_library_init();
96 printf("ass_library_init failed!\n");
100 ass_set_message_cb(ass_library
, msg_callback
, NULL
);
102 ass_renderer
= ass_renderer_init(ass_library
);
104 printf("ass_renderer_init failed!\n");
108 ass_set_frame_size(ass_renderer
, frame_w
, frame_h
);
109 ass_set_fonts(ass_renderer
, NULL
, "Sans", 1, NULL
, 1);
112 static image_t
*gen_image(int width
, int height
)
114 image_t
*img
= malloc(sizeof(image_t
));
116 img
->height
= height
;
117 img
->stride
= width
* 3;
118 img
->buffer
= (unsigned char *) calloc(1, height
* width
* 3);
119 memset(img
->buffer
, 63, img
->stride
* img
->height
);
120 //for (int i = 0; i < height * width * 3; ++i)
121 // img->buffer[i] = (i/3/50) % 100;
125 #define _r(c) ((c)>>24)
126 #define _g(c) (((c)>>16)&0xFF)
127 #define _b(c) (((c)>>8)&0xFF)
128 #define _a(c) ((c)&0xFF)
130 static void blend_single(image_t
* frame
, ASS_Image
*img
)
133 unsigned char opacity
= 255 - _a(img
->color
);
134 unsigned char r
= _r(img
->color
);
135 unsigned char g
= _g(img
->color
);
136 unsigned char b
= _b(img
->color
);
142 dst
= frame
->buffer
+ img
->dst_y
* frame
->stride
+ img
->dst_x
* 3;
143 for (y
= 0; y
< img
->h
; ++y
) {
144 for (x
= 0; x
< img
->w
; ++x
) {
145 unsigned k
= ((unsigned) src
[x
]) * opacity
/ 255;
146 // possible endianness problems
147 dst
[x
* 3] = (k
* b
+ (255 - k
) * dst
[x
* 3]) / 255;
148 dst
[x
* 3 + 1] = (k
* g
+ (255 - k
) * dst
[x
* 3 + 1]) / 255;
149 dst
[x
* 3 + 2] = (k
* r
+ (255 - k
) * dst
[x
* 3 + 2]) / 255;
152 dst
+= frame
->stride
;
156 static void blend(image_t
* frame
, ASS_Image
*img
)
160 blend_single(frame
, img
);
164 printf("%d images blended\n", cnt
);
167 int main(int argc
, char *argv
[])
169 const int frame_w
= 640;
170 const int frame_h
= 480;
173 printf("usage: %s <image file> <subtitle file> <time>\n", argv
[0]);
176 char *imgfile
= argv
[1];
177 char *subfile
= argv
[2];
178 double tm
= strtod(argv
[3], 0);
180 init(frame_w
, frame_h
);
181 ASS_Track
*track
= ass_read_file(ass_library
, subfile
, NULL
);
183 printf("track init failed!\n");
188 ass_render_frame(ass_renderer
, track
, (int) (tm
* 1000), NULL
);
189 image_t
*frame
= gen_image(frame_w
, frame_h
);
192 ass_free_track(track
);
193 ass_renderer_done(ass_renderer
);
194 ass_library_done(ass_library
);
196 write_png(imgfile
, frame
);