diff options
author | Grigori Goronzy <greg@blackbox> | 2009-07-11 02:57:17 +0200 |
---|---|---|
committer | Grigori Goronzy <greg@blackbox> | 2009-07-11 02:57:17 +0200 |
commit | 9938df3a44d71ec214a70200749a99cfc33dd814 (patch) | |
tree | 8de1299867faebb61fd5bfd799bdb57a8df2a30b /test/test.c | |
parent | cd0bf3db35a4fa0e7f5ac52453755f7f1f2d444f (diff) | |
download | libass-9938df3a44d71ec214a70200749a99cfc33dd814.tar.bz2 libass-9938df3a44d71ec214a70200749a99cfc33dd814.tar.xz |
Convert test program to plain C
The test program unnecessarily was using a few C++ features. Convert it
to plain C to make everything work without a C++ compiler.
Diffstat (limited to 'test/test.c')
-rw-r--r-- | test/test.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/test/test.c b/test/test.c new file mode 100644 index 00000000..47b7f292 --- /dev/null +++ b/test/test.c @@ -0,0 +1,181 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <ass.h> +#include <png.h> + +typedef struct image_s { + int width, height, stride; + unsigned char *buffer; // RGB24 +} image_t; + +ass_library_t *ass_library; +ass_renderer_t *ass_renderer; + +void msg_callback(int level, char *fmt, va_list * va) +{ + if (level > 6) + return; + printf("libass: "); + vprintf(fmt, *va); + printf("\n"); +} + +static void write_png(char *fname, image_t * img) +{ + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + png_byte **row_pointers; + int k; + + png_ptr = + png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info_ptr = png_create_info_struct(png_ptr); + fp = NULL; + + if (setjmp(png_ptr->jmpbuf)) { + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + return; + } + + fp = fopen(fname, "wb"); + if (fp == NULL) { + printf("PNG Error opening %s for writing!\n", fname); + return; + } + + png_init_io(png_ptr, fp); + png_set_compression_level(png_ptr, 0); + + png_set_IHDR(png_ptr, info_ptr, img->width, img->height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + png_write_info(png_ptr, info_ptr); + + png_set_bgr(png_ptr); + + row_pointers = (png_byte **) malloc(img->height * sizeof(png_byte *)); + for (k = 0; k < img->height; k++) + row_pointers[k] = img->buffer + img->stride * k; + + png_write_image(png_ptr, row_pointers); + png_write_end(png_ptr, info_ptr); + png_destroy_write_struct(&png_ptr, &info_ptr); + + free(row_pointers); + + fclose(fp); +} + +static void init(int frame_w, int frame_h) +{ + ass_library = ass_library_init(); + if (!ass_library) { + printf("ass_library_init failed!\n"); + exit(1); + } + + ass_set_fonts_dir(ass_library, ""); + ass_set_extract_fonts(ass_library, 0); + ass_set_style_overrides(ass_library, NULL); + ass_set_message_cb(ass_library, msg_callback); + + ass_renderer = ass_renderer_init(ass_library); + if (!ass_renderer) { + printf("ass_renderer_init failed!\n"); + exit(1); + } + + ass_set_frame_size(ass_renderer, frame_w, frame_h); + ass_set_margins(ass_renderer, 0, 0, 0, 0); + ass_set_use_margins(ass_renderer, 0); + ass_set_font_scale(ass_renderer, 1.); + ass_set_fonts(ass_renderer, NULL, "Sans", 1, NULL); +} + +static image_t *gen_image(int width, int height) +{ + image_t *img = malloc(sizeof(image_t)); + img->width = width; + img->height = height; + img->stride = width * 3; + img->buffer = (unsigned char *) calloc(1, height * width * 3); + memset(img->buffer, 63, img->stride * img->height); + //for (int i = 0; i < height * width * 3; ++i) + // img->buffer[i] = (i/3/50) % 100; + return img; +} + +#define _r(c) ((c)>>24) +#define _g(c) (((c)>>16)&0xFF) +#define _b(c) (((c)>>8)&0xFF) +#define _a(c) ((c)&0xFF) + +static void blend_single(image_t * frame, ass_image_t * img) +{ + int x, y; + unsigned char opacity = 255 - _a(img->color); + unsigned char r = _r(img->color); + unsigned char g = _g(img->color); + unsigned char b = _b(img->color); + + unsigned char *src; + unsigned char *dst; + + src = img->bitmap; + dst = frame->buffer + img->dst_y * frame->stride + img->dst_x * 3; + for (y = 0; y < img->h; ++y) { + for (x = 0; x < img->w; ++x) { + unsigned k = ((unsigned) src[x]) * opacity / 255; + // possible endianness problems + dst[x * 3] = (k * b + (255 - k) * dst[x * 3]) / 255; + dst[x * 3 + 1] = (k * g + (255 - k) * dst[x * 3 + 1]) / 255; + dst[x * 3 + 2] = (k * r + (255 - k) * dst[x * 3 + 2]) / 255; + } + src += img->stride; + dst += frame->stride; + } +} + +static void blend(image_t * frame, ass_image_t * img) +{ + int cnt = 0; + while (img) { + blend_single(frame, img); + ++cnt; + img = img->next; + } + printf("%d images blended\n", cnt); +} + +int main(int argc, char *argv[]) +{ + const int frame_w = 640; + const int frame_h = 480; + + if (argc < 4) { + printf("usage: %s <image file> <subtitle file> <time>\n", argv[0]); + exit(1); + } + char *imgfile = argv[1]; + char *subfile = argv[2]; + double tm = strtod(argv[3], 0); + + init(frame_w, frame_h); + ass_track_t *track = ass_read_file(ass_library, subfile, NULL); + if (!track) { + printf("track init failed!\n"); + return 1; + } + + ass_image_t *img = + ass_render_frame(ass_renderer, track, (int) (tm * 1000), NULL); + image_t *frame = gen_image(frame_w, frame_h); + blend(frame, img); + write_png(imgfile, frame); + + return 0; +} |