]> granicus.if.org Git - libass/blob - test/test.cpp
Remove wrappers for ass_set_fonts
[libass] / test / test.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdexcept>
4
5 extern "C" {
6 #include <ass.h>
7 }
8
9 #include <png.h>
10
11 struct image_t {
12   int width, height, stride;
13   unsigned char* buffer; // RGB24
14 };
15
16 ass_library_t* ass_library;
17 ass_renderer_t* ass_renderer;
18
19 static void write_png(char *fname, image_t* img)
20 {
21     FILE * fp;
22     png_structp png_ptr;
23     png_infop info_ptr;
24     png_byte **row_pointers;
25     int k;
26
27     png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
28     info_ptr = png_create_info_struct(png_ptr);
29     fp = NULL;
30
31     if (setjmp(png_ptr->jmpbuf)) {
32         png_destroy_write_struct(&png_ptr, &info_ptr);
33         fclose(fp);
34         return;
35     }
36
37     fp = fopen (fname, "wb");
38     if (fp == NULL) {
39         printf("PNG Error opening %s for writing!\n", fname);
40         return;
41     }
42         
43     png_init_io(png_ptr, fp);
44     png_set_compression_level(png_ptr, 0);
45
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);
49
50     png_write_info(png_ptr, info_ptr);
51         
52     png_set_bgr(png_ptr);
53
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;
57
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);
61
62     free(row_pointers);
63
64     fclose (fp);
65 }
66
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");
70   
71   ass_set_fonts_dir(ass_library, "");
72   ass_set_extract_fonts(ass_library, 0);
73   ass_set_style_overrides(ass_library, NULL);
74
75   ass_renderer = ass_renderer_init(ass_library);
76   if (!ass_renderer) throw std::runtime_error("ass_renderer_init failed");
77   
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);
83 }
84
85 static image_t* gen_image(int width, int height) {
86   image_t* img = new image_t;
87   img->width = width;
88   img->height = height;
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;
93   return img;
94 }
95
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)
100
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);
106   
107   unsigned char* src;
108   unsigned char* dst;
109
110   src = img->bitmap;
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;
119     }
120     src += img->stride;
121     dst += frame->stride;
122   }
123 }
124
125 static void blend(image_t* frame, ass_image_t* img) {
126   int cnt = 0;
127   while (img) {
128     blend_single(frame, img);
129     ++cnt;
130     img = img->next;
131   }
132   printf("%d images blended\n", cnt);
133 }
134
135 int main(int argc, char* argv[]) {
136   const int frame_w = 640;
137   const int frame_h = 480;
138   
139   if (argc < 4) {
140     printf("usage: %s <image file> <subtitle file> <time>\n", argv[0]);
141     exit(1);
142   }
143   char* imgfile = argv[1];
144   char* subfile = argv[2];
145   double tm = strtod(argv[3], 0);
146
147   init(frame_w, frame_h);
148   ass_track_t* track = ass_read_file(ass_library, subfile, NULL);
149   
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);
152   blend(frame, img);
153   write_png(imgfile, frame);
154
155   return 0;
156 }