6 #define RENDER_MAGIC 0x765AE
8 typedef void (*render_color_f)(i_render *, int, int, int, unsigned char const *src, i_color const *color);
12 static void IM_SUFFIX(render_color_alpha)(i_render *r, int x, int y, int width, unsigned char const *src, i_color const *color);
13 static void IM_SUFFIX(render_color_13)(i_render *r, int x, int y, int width, unsigned char const *src, i_color const *color);
15 static render_color_f IM_SUFFIX(render_color_tab)[] =
18 IM_SUFFIX(render_color_13),
19 IM_SUFFIX(render_color_alpha),
20 IM_SUFFIX(render_color_13),
21 IM_SUFFIX(render_color_alpha),
27 i_render_init(i_render *r, i_img *im, int width) {
28 r->magic = RENDER_MAGIC;
32 r->line_double = NULL;
34 r->IM_SUFFIX(line) = mymalloc(sizeof(i_fcolor) * width);
39 i_render_done(i_render *r) {
43 myfree(r->line_double);
48 i_render_color(i_render *r, int x, int y, int width, unsigned char const *src,
49 i_color const *color) {
51 if (y < 0 || y >= im->ysize)
58 if (x + width > im->xsize) {
59 width = im->xsize - x;
61 if (x >= im->xsize || x + width <= 0 || width <= 0)
64 /* avoid as much work as we can */
65 while (width > 0 && *src == 0) {
70 while (width > 0 && src[width-1] == 0) {
76 /* make sure our line buffer is big enough */
77 if (width > r->width) {
78 int new_width = r->width * 2;
79 if (new_width < width)
83 r->line_8 = myrealloc(r->line_8, sizeof(i_color) * new_width);
85 r->line_double = myrealloc(r->line_double, sizeof(i_fcolor) * new_width);
88 #code r->im->bits <= 8
89 (IM_SUFFIX(render_color_tab)[im->channels])(r, x, y, width, src, color);
94 dump_src(const char *note, unsigned char const *src, int width) {
96 printf("%s - %p/%d\n", note, src, width);
97 for (i = 0; i < width; ++i) {
98 printf("%02x ", src[i]);
107 IM_SUFFIX(render_color_13)(i_render *r, int x, int y, int width,
108 unsigned char const *src, i_color const *color) {
110 IM_COLOR *linep = r->IM_SUFFIX(line);
111 int ch, channels = im->channels;
115 #define STORE_COLOR (*color)
119 for (ch = 0; ch < channels; ++ch) {
120 fcolor.channel[ch] = color->channel[ch] / 255.0;
122 #define STORE_COLOR fcolor
126 while (fetch_offset < width && *src == 0xFF) {
127 *linep++ = STORE_COLOR;
131 IM_GLIN(im, x+fetch_offset, x+width, y, linep);
132 while (fetch_offset < width) {
134 IM_WORK_T alpha = *src++;
136 IM_WORK_T alpha = *src++ / 255.0;
138 if (alpha == IM_SAMPLE_MAX)
139 *linep = STORE_COLOR;
141 for (ch = 0; ch < channels; ++ch) {
142 linep->channel[ch] = (linep->channel[ch] * (IM_SAMPLE_MAX - alpha)
143 + STORE_COLOR.channel[ch] * alpha) / IM_SAMPLE_MAX;
149 IM_PLIN(im, x, x+width, y, r->IM_SUFFIX(line));
154 IM_SUFFIX(render_color_alpha)(i_render *r, int x, int y, int width,
155 unsigned char const *src, i_color const *color) {
156 IM_COLOR *linep = r->IM_SUFFIX(line);
158 int alpha_channel = r->im->channels - 1;
162 #define STORE_COLOR (*color)
166 for (ch = 0; ch < r->im->channels; ++ch) {
167 fcolor.channel[ch] = color->channel[ch] / 255.0;
169 #define STORE_COLOR fcolor
173 while (fetch_offset < width && *src == 0xFF) {
174 *linep++ = STORE_COLOR;
178 IM_GLIN(r->im, x+fetch_offset, x+width, y, linep);
179 while (fetch_offset < width) {
181 IM_WORK_T src_alpha = *src++;
183 IM_WORK_T src_alpha = *src++ / 255.0;
185 if (src_alpha == IM_SAMPLE_MAX)
186 *linep = STORE_COLOR;
187 else if (src_alpha) {
188 IM_WORK_T remains = IM_SAMPLE_MAX - src_alpha;
189 IM_WORK_T orig_alpha = linep->channel[alpha_channel];
190 IM_WORK_T dest_alpha = src_alpha + (remains * orig_alpha) / IM_SAMPLE_MAX;
191 for (ch = 0; ch < alpha_channel; ++ch) {
192 linep->channel[ch] = ( src_alpha * STORE_COLOR.channel[ch]
193 + remains * linep->channel[ch] * orig_alpha / IM_SAMPLE_MAX
196 linep->channel[alpha_channel] = dest_alpha;
201 IM_PLIN(r->im, x, x+width, y, r->IM_SUFFIX(line));