Magellan Linux

Contents of /trunk/directfb/patches/directfb-1.2.10-libpng15.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1304 - (show annotations) (download)
Fri Mar 11 23:02:07 2011 UTC (13 years, 1 month ago) by niro
File size: 66940 byte(s)
fixed patch
1 diff -Naur DirectFB-1.2.10/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c DirectFB-1.2.10-magellan/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c
2 --- DirectFB-1.2.10/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c 2009-08-27 21:54:18.000000000 +0200
3 +++ DirectFB-1.2.10-magellan/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c 2011-03-12 00:13:13.000000000 +0100
4 @@ -204,7 +204,7 @@
5 if (!data->png_ptr)
6 goto error;
7
8 - if (setjmp( data->png_ptr->jmpbuf )) {
9 + if (png_jmpbuf( data->png_ptr )) {
10 D_ERROR( "ImageProvider/PNG: Error reading header!\n" );
11 goto error;
12 }
13 @@ -331,7 +331,7 @@
14 rect = dst_data->area.wanted;
15 }
16
17 - if (setjmp( data->png_ptr->jmpbuf )) {
18 + if (png_jmpbuf( data->png_ptr )) {
19 D_ERROR( "ImageProvider/PNG: Error during decoding!\n" );
20
21 if (data->stage < STAGE_IMAGE)
22 @@ -350,6 +350,7 @@
23 /* actual rendering */
24 if (dfb_rectangle_region_intersects( &rect, &clip )) {
25 CoreSurfaceBufferLock lock;
26 + png_byte bit_depth = png_get_bit_depth( data->png_ptr, data->info_ptr );
27
28 ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAF_CPU_WRITE, &lock );
29 if (ret)
30 @@ -357,7 +358,7 @@
31
32 switch (data->color_type) {
33 case PNG_COLOR_TYPE_PALETTE:
34 - if (dst_surface->config.format == DSPF_LUT8 && data->info_ptr->bit_depth == 8) {
35 + if (dst_surface->config.format == DSPF_LUT8 && bit_depth == 8) {
36 /*
37 * Special indexed PNG to LUT8 loading.
38 */
39 @@ -400,7 +401,7 @@
40 }
41 else {
42 if (data->color_type == PNG_COLOR_TYPE_GRAY) {
43 - int num = 1 << data->info_ptr->bit_depth;
44 + int num = 1 << bit_depth;
45
46 for (x=0; x<num; x++) {
47 int value = x * 255 / (num - 1);
48 @@ -409,7 +410,7 @@
49 }
50 }
51
52 - switch (data->info_ptr->bit_depth) {
53 + switch (bit_depth) {
54 case 8:
55 for (y=0; y<data->height; y++) {
56 u8 *S = data->image + data->pitch * y;
57 @@ -464,7 +465,7 @@
58
59 default:
60 D_ERROR( "ImageProvider/PNG: Unsupported indexed bit depth %d!\n",
61 - data->info_ptr->bit_depth );
62 + bit_depth );
63 }
64
65 dfb_scale_linear_32( image_argb, data->width, data->height,
66 @@ -630,16 +631,26 @@
67 NULL, NULL, NULL );
68
69 if (png_get_valid( data->png_ptr, data->info_ptr, PNG_INFO_tRNS )) {
70 + png_bytep trans;
71 + png_color_16p trans_color;
72 + int num_trans;
73 +
74 + png_get_tRNS( data->png_ptr, data->info_ptr, &trans, &num_trans, &trans_color );
75 +
76 data->color_keyed = true;
77
78 /* generate color key based on palette... */
79 if (data->color_type == PNG_COLOR_TYPE_PALETTE) {
80 u32 key;
81 - png_colorp palette = data->info_ptr->palette;
82 - png_bytep trans = data->info_ptr->trans;
83 - int num_colors = MIN( MAXCOLORMAPSIZE,
84 - data->info_ptr->num_palette );
85 - u8 cmap[3][num_colors];
86 + png_colorp palette;
87 + int num_colors;
88 + u8 *cmap[3];
89 +
90 + png_get_PLTE( data->png_ptr, data->info_ptr, &palette, &num_colors );
91 + num_colors = MIN( MAXCOLORMAPSIZE, num_colors );
92 + cmap[0] = alloca (num_colors);
93 + cmap[1] = alloca (num_colors);
94 + cmap[2] = alloca (num_colors);
95
96 for (i=0; i<num_colors; i++) {
97 cmap[0][i] = palette[i].red;
98 @@ -649,7 +660,7 @@
99
100 key = FindColorKey( num_colors, &cmap[0][0] );
101
102 - for (i=0; i<data->info_ptr->num_trans; i++) {
103 + for (i=0; i<num_trans; i++) {
104 if (!trans[i]) {
105 palette[i].red = (key & 0xff0000) >> 16;
106 palette[i].green = (key & 0x00ff00) >> 8;
107 @@ -661,20 +672,23 @@
108 }
109 else {
110 /* ...or based on trans rgb value */
111 - png_color_16p trans = &data->info_ptr->trans_values;
112 -
113 - data->color_key = (((trans->red & 0xff00) << 8) |
114 - ((trans->green & 0xff00)) |
115 - ((trans->blue & 0xff00) >> 8));
116 + data->color_key = (((trans_color->red & 0xff00) << 8) |
117 + ((trans_color->green & 0xff00)) |
118 + ((trans_color->blue & 0xff00) >> 8));
119 }
120 }
121
122 switch (data->color_type) {
123 case PNG_COLOR_TYPE_PALETTE: {
124 - png_colorp palette = data->info_ptr->palette;
125 - png_bytep trans = data->info_ptr->trans;
126 - int num_trans = data->info_ptr->num_trans;
127 - int num_colors = MIN( MAXCOLORMAPSIZE, data->info_ptr->num_palette );
128 + png_colorp palette;
129 + png_bytep trans;
130 + png_color_16p trans_color;
131 + int num_trans;
132 + int num_colors;
133 +
134 + png_get_PLTE( data->png_ptr, data->info_ptr, &palette, &num_colors );
135 + num_colors = MIN( MAXCOLORMAPSIZE, num_colors );
136 + png_get_tRNS( data->png_ptr, data->info_ptr, &trans, &num_trans, &trans_color );
137
138 for (i=0; i<num_colors; i++) {
139 data->colors[i].a = (i < num_trans) ? trans[i] : 0xff;
140 diff -Naur DirectFB-1.2.10/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c~ DirectFB-1.2.10-magellan/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c~
141 --- DirectFB-1.2.10/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c~ 1970-01-01 01:00:00.000000000 +0100
142 +++ DirectFB-1.2.10-magellan/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c~ 2011-03-12 00:13:13.000000000 +0100
143 @@ -0,0 +1,861 @@
144 +/*
145 + (c) Copyright 2001-2008 The world wide DirectFB Open Source Community (directfb.org)
146 + (c) Copyright 2000-2004 Convergence (integrated media) GmbH
147 +
148 + All rights reserved.
149 +
150 + Written by Denis Oliver Kropp <dok@directfb.org>,
151 + Andreas Hundt <andi@fischlustig.de>,
152 + Sven Neumann <neo@directfb.org>,
153 + Ville Syrjälä <syrjala@sci.fi> and
154 + Claudio Ciccani <klan@users.sf.net>.
155 +
156 + This library is free software; you can redistribute it and/or
157 + modify it under the terms of the GNU Lesser General Public
158 + License as published by the Free Software Foundation; either
159 + version 2 of the License, or (at your option) any later version.
160 +
161 + This library is distributed in the hope that it will be useful,
162 + but WITHOUT ANY WARRANTY; without even the implied warranty of
163 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
164 + Lesser General Public License for more details.
165 +
166 + You should have received a copy of the GNU Lesser General Public
167 + License along with this library; if not, write to the
168 + Free Software Foundation, Inc., 59 Temple Place - Suite 330,
169 + Boston, MA 02111-1307, USA.
170 +*/
171 +
172 +#include <config.h>
173 +
174 +#include <errno.h>
175 +#include <stdio.h>
176 +#include <stdlib.h>
177 +#include <unistd.h>
178 +#include <png.h>
179 +#include <string.h>
180 +#include <stdarg.h>
181 +
182 +#include <directfb.h>
183 +
184 +#include <display/idirectfbsurface.h>
185 +
186 +#include <media/idirectfbimageprovider.h>
187 +
188 +#include <core/coredefs.h>
189 +#include <core/coretypes.h>
190 +
191 +#include <core/layers.h>
192 +#include <core/palette.h>
193 +#include <core/surface.h>
194 +
195 +#include <misc/gfx_util.h>
196 +#include <misc/util.h>
197 +
198 +#include <gfx/clip.h>
199 +#include <gfx/convert.h>
200 +
201 +#include <direct/interface.h>
202 +#include <direct/mem.h>
203 +#include <direct/memcpy.h>
204 +#include <direct/messages.h>
205 +#include <direct/util.h>
206 +
207 +#include "config.h"
208 +
209 +static DFBResult
210 +Probe( IDirectFBImageProvider_ProbeContext *ctx );
211 +
212 +static DFBResult
213 +Construct( IDirectFBImageProvider *thiz,
214 + ... );
215 +
216 +#include <direct/interface_implementation.h>
217 +
218 +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, PNG )
219 +
220 +
221 +enum {
222 + STAGE_ABORT = -2,
223 + STAGE_ERROR = -1,
224 + STAGE_START = 0,
225 + STAGE_INFO,
226 + STAGE_IMAGE,
227 + STAGE_END
228 +};
229 +
230 +/*
231 + * private data struct of IDirectFBImageProvider_PNG
232 + */
233 +typedef struct {
234 + int ref; /* reference counter */
235 + IDirectFBDataBuffer *buffer;
236 +
237 + int stage;
238 + int rows;
239 +
240 + png_structp png_ptr;
241 + png_infop info_ptr;
242 +
243 + png_uint_32 width;
244 + png_uint_32 height;
245 + int bpp;
246 + int color_type;
247 + png_uint_32 color_key;
248 + bool color_keyed;
249 +
250 + void *image;
251 + int pitch;
252 + u32 palette[256];
253 + DFBColor colors[256];
254 +
255 + DIRenderCallback render_callback;
256 + void *render_callback_context;
257 +
258 + CoreDFB *core;
259 +} IDirectFBImageProvider_PNG_data;
260 +
261 +static DirectResult
262 +IDirectFBImageProvider_PNG_AddRef ( IDirectFBImageProvider *thiz );
263 +
264 +static DirectResult
265 +IDirectFBImageProvider_PNG_Release ( IDirectFBImageProvider *thiz );
266 +
267 +static DFBResult
268 +IDirectFBImageProvider_PNG_RenderTo( IDirectFBImageProvider *thiz,
269 + IDirectFBSurface *destination,
270 + const DFBRectangle *destination_rect );
271 +
272 +static DFBResult
273 +IDirectFBImageProvider_PNG_SetRenderCallback( IDirectFBImageProvider *thiz,
274 + DIRenderCallback callback,
275 + void *context );
276 +
277 +static DFBResult
278 +IDirectFBImageProvider_PNG_GetSurfaceDescription( IDirectFBImageProvider *thiz,
279 + DFBSurfaceDescription *dsc );
280 +
281 +static DFBResult
282 +IDirectFBImageProvider_PNG_GetImageDescription( IDirectFBImageProvider *thiz,
283 + DFBImageDescription *dsc );
284 +
285 +/* Called at the start of the progressive load, once we have image info */
286 +static void
287 +png_info_callback (png_structp png_read_ptr,
288 + png_infop png_info_ptr);
289 +
290 +/* Called for each row; note that you will get duplicate row numbers
291 + for interlaced PNGs */
292 +static void
293 +png_row_callback (png_structp png_read_ptr,
294 + png_bytep new_row,
295 + png_uint_32 row_num,
296 + int pass_num);
297 +
298 +/* Called after reading the entire image */
299 +static void
300 +png_end_callback (png_structp png_read_ptr,
301 + png_infop png_info_ptr);
302 +
303 +/* Pipes data into libpng until stage is different from the one specified. */
304 +static DFBResult
305 +push_data_until_stage (IDirectFBImageProvider_PNG_data *data,
306 + int stage,
307 + int buffer_size);
308 +
309 +/**********************************************************************************************************************/
310 +
311 +static DFBResult
312 +Probe( IDirectFBImageProvider_ProbeContext *ctx )
313 +{
314 + if (png_check_sig( ctx->header, 8 ))
315 + return DFB_OK;
316 +
317 + return DFB_UNSUPPORTED;
318 +}
319 +
320 +static DFBResult
321 +Construct( IDirectFBImageProvider *thiz,
322 + ... )
323 +{
324 + DFBResult ret = DFB_FAILURE;
325 +
326 + IDirectFBDataBuffer *buffer;
327 + CoreDFB *core;
328 + va_list tag;
329 +
330 + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_PNG)
331 +
332 + va_start( tag, thiz );
333 + buffer = va_arg( tag, IDirectFBDataBuffer * );
334 + core = va_arg( tag, CoreDFB * );
335 + va_end( tag );
336 +
337 + data->ref = 1;
338 + data->buffer = buffer;
339 + data->core = core;
340 +
341 + /* Increase the data buffer reference counter. */
342 + buffer->AddRef( buffer );
343 +
344 + /* Create the PNG read handle. */
345 + data->png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING,
346 + NULL, NULL, NULL );
347 + if (!data->png_ptr)
348 + goto error;
349 +
350 + if (png_jmpbuf( data->png_ptr )) {
351 + D_ERROR( "ImageProvider/PNG: Error reading header!\n" );
352 + goto error;
353 + }
354 +
355 + /* Create the PNG info handle. */
356 + data->info_ptr = png_create_info_struct( data->png_ptr );
357 + if (!data->info_ptr)
358 + goto error;
359 +
360 + /* Setup progressive image loading. */
361 + png_set_progressive_read_fn( data->png_ptr, data,
362 + png_info_callback,
363 + png_row_callback,
364 + png_end_callback );
365 +
366 +
367 + /* Read until info callback is called. */
368 + ret = push_data_until_stage( data, STAGE_INFO, 64 );
369 + if (ret)
370 + goto error;
371 +
372 + thiz->AddRef = IDirectFBImageProvider_PNG_AddRef;
373 + thiz->Release = IDirectFBImageProvider_PNG_Release;
374 + thiz->RenderTo = IDirectFBImageProvider_PNG_RenderTo;
375 + thiz->SetRenderCallback = IDirectFBImageProvider_PNG_SetRenderCallback;
376 + thiz->GetImageDescription = IDirectFBImageProvider_PNG_GetImageDescription;
377 + thiz->GetSurfaceDescription = IDirectFBImageProvider_PNG_GetSurfaceDescription;
378 +
379 + return DFB_OK;
380 +
381 +error:
382 + if (data->png_ptr)
383 + png_destroy_read_struct( &data->png_ptr, &data->info_ptr, NULL );
384 +
385 + buffer->Release( buffer );
386 +
387 + if (data->image)
388 + D_FREE( data->image );
389 +
390 + DIRECT_DEALLOCATE_INTERFACE(thiz);
391 +
392 + return ret;
393 +}
394 +
395 +/**********************************************************************************************************************/
396 +
397 +static void
398 +IDirectFBImageProvider_PNG_Destruct( IDirectFBImageProvider *thiz )
399 +{
400 + IDirectFBImageProvider_PNG_data *data =
401 + (IDirectFBImageProvider_PNG_data*)thiz->priv;
402 +
403 + png_destroy_read_struct( &data->png_ptr, &data->info_ptr, NULL );
404 +
405 + /* Decrease the data buffer reference counter. */
406 + data->buffer->Release( data->buffer );
407 +
408 + /* Deallocate image data. */
409 + if (data->image)
410 + D_FREE( data->image );
411 +
412 + DIRECT_DEALLOCATE_INTERFACE( thiz );
413 +}
414 +
415 +static DirectResult
416 +IDirectFBImageProvider_PNG_AddRef( IDirectFBImageProvider *thiz )
417 +{
418 + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG)
419 +
420 + data->ref++;
421 +
422 + return DFB_OK;
423 +}
424 +
425 +static DirectResult
426 +IDirectFBImageProvider_PNG_Release( IDirectFBImageProvider *thiz )
427 +{
428 + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG)
429 +
430 + if (--data->ref == 0) {
431 + IDirectFBImageProvider_PNG_Destruct( thiz );
432 + }
433 +
434 + return DFB_OK;
435 +}
436 +
437 +/**********************************************************************************************************************/
438 +
439 +static DFBResult
440 +IDirectFBImageProvider_PNG_RenderTo( IDirectFBImageProvider *thiz,
441 + IDirectFBSurface *destination,
442 + const DFBRectangle *dest_rect )
443 +{
444 + DFBResult ret = DFB_OK;
445 + IDirectFBSurface_data *dst_data;
446 + CoreSurface *dst_surface;
447 + DFBRegion clip;
448 + DFBRectangle rect;
449 + png_infop info;
450 + int x, y;
451 +
452 + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG)
453 +
454 + info = data->info_ptr;
455 +
456 + dst_data = (IDirectFBSurface_data*) destination->priv;
457 + if (!dst_data)
458 + return DFB_DEAD;
459 +
460 + dst_surface = dst_data->surface;
461 + if (!dst_surface)
462 + return DFB_DESTROYED;
463 +
464 + dfb_region_from_rectangle( &clip, &dst_data->area.current );
465 +
466 + if (dest_rect) {
467 + if (dest_rect->w < 1 || dest_rect->h < 1)
468 + return DFB_INVARG;
469 + rect = *dest_rect;
470 + rect.x += dst_data->area.wanted.x;
471 + rect.y += dst_data->area.wanted.y;
472 + }
473 + else {
474 + rect = dst_data->area.wanted;
475 + }
476 +
477 + if (png_jmpbuf( data->png_ptr )) {
478 + D_ERROR( "ImageProvider/PNG: Error during decoding!\n" );
479 +
480 + if (data->stage < STAGE_IMAGE)
481 + return DFB_FAILURE;
482 +
483 + data->stage = STAGE_ERROR;
484 + }
485 +
486 + /* Read until image is completely decoded. */
487 + if (data->stage != STAGE_ERROR) {
488 + ret = push_data_until_stage( data, STAGE_END, 16384 );
489 + if (ret)
490 + return ret;
491 + }
492 +
493 + /* actual rendering */
494 + if (dfb_rectangle_region_intersects( &rect, &clip )) {
495 + CoreSurfaceBufferLock lock;
496 + png_byte bit_depth = png_get_bit_depth( data->png_ptr, data->info_ptr );
497 +
498 + ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAF_CPU_WRITE, &lock );
499 + if (ret)
500 + return ret;
501 +
502 + switch (data->color_type) {
503 + case PNG_COLOR_TYPE_PALETTE:
504 + if (dst_surface->config.format == DSPF_LUT8 && bit_depth == 8) {
505 + /*
506 + * Special indexed PNG to LUT8 loading.
507 + */
508 +
509 + /* FIXME: Limitation for LUT8 is to load complete surface only. */
510 + dfb_clip_rectangle( &clip, &rect );
511 + if (rect.x == 0 && rect.y == 0 &&
512 + rect.w == dst_surface->config.size.w &&
513 + rect.h == dst_surface->config.size.h &&
514 + rect.w == data->width &&
515 + rect.h == data->height)
516 + {
517 + for (y=0; y<data->height; y++)
518 + direct_memcpy( lock.addr + lock.pitch * y,
519 + data->image + data->pitch * y,
520 + data->width );
521 +
522 + break;
523 + }
524 + }
525 + /* fall through */
526 +
527 + case PNG_COLOR_TYPE_GRAY: {
528 + /*
529 + * Convert to ARGB and use generic loading code.
530 + */
531 +
532 + // FIXME: allocates four additional bytes because the scaling functions
533 + // in src/misc/gfx_util.c have an off-by-one bug which causes
534 + // segfaults on darwin/osx (not on linux)
535 + int size = data->width * data->height * 4 + 4;
536 +
537 + /* allocate image data */
538 + void *image_argb = D_MALLOC( size );
539 +
540 + if (!image_argb) {
541 + D_ERROR( "DirectFB/ImageProvider_PNG: Could not "
542 + "allocate %d bytes of system memory!\n", size );
543 + ret = DFB_NOSYSTEMMEMORY;
544 + }
545 + else {
546 + if (data->color_type == PNG_COLOR_TYPE_GRAY) {
547 + int num = 1 << bit_depth;
548 +
549 + for (x=0; x<num; x++) {
550 + int value = x * 255 / (num - 1);
551 +
552 + data->palette[x] = 0xff000000 | (value << 16) | (value << 8) | value;
553 + }
554 + }
555 +
556 + switch (bit_depth) {
557 + case 8:
558 + for (y=0; y<data->height; y++) {
559 + u8 *S = data->image + data->pitch * y;
560 + u32 *D = image_argb + data->width * y * 4;
561 +
562 + for (x=0; x<data->width; x++)
563 + D[x] = data->palette[ S[x] ];
564 + }
565 + break;
566 +
567 + case 4:
568 + for (y=0; y<data->height; y++) {
569 + u8 *S = data->image + data->pitch * y;
570 + u32 *D = image_argb + data->width * y * 4;
571 +
572 + for (x=0; x<data->width; x++) {
573 + if (x & 1)
574 + D[x] = data->palette[ S[x>>1] & 0xf ];
575 + else
576 + D[x] = data->palette[ S[x>>1] >> 4 ];
577 + }
578 + }
579 + break;
580 +
581 + case 2:
582 + for (y=0; y<data->height; y++) {
583 + int n = 6;
584 + u8 *S = data->image + data->pitch * y;
585 + u32 *D = image_argb + data->width * y * 4;
586 +
587 + for (x=0; x<data->width; x++) {
588 + D[x] = data->palette[ (S[x>>2] >> n) & 3 ];
589 +
590 + n = (n ? n - 2 : 6);
591 + }
592 + }
593 + break;
594 +
595 + case 1:
596 + for (y=0; y<data->height; y++) {
597 + int n = 7;
598 + u8 *S = data->image + data->pitch * y;
599 + u32 *D = image_argb + data->width * y * 4;
600 +
601 + for (x=0; x<data->width; x++) {
602 + D[x] = data->palette[ (S[x>>3] >> n) & 1 ];
603 +
604 + n = (n ? n - 1 : 7);
605 + }
606 + }
607 + break;
608 +
609 + default:
610 + D_ERROR( "ImageProvider/PNG: Unsupported indexed bit depth %d!\n",
611 + bit_depth );
612 + }
613 +
614 + dfb_scale_linear_32( image_argb, data->width, data->height,
615 + lock.addr, lock.pitch, &rect, dst_surface, &clip );
616 +
617 + D_FREE( image_argb );
618 + }
619 + break;
620 + }
621 + default:
622 + /*
623 + * Generic loading code.
624 + */
625 + dfb_scale_linear_32( data->image, data->width, data->height,
626 + lock.addr, lock.pitch, &rect, dst_surface, &clip );
627 + break;
628 + }
629 +
630 + dfb_surface_unlock_buffer( dst_surface, &lock );
631 + }
632 +
633 + if (data->stage != STAGE_END)
634 + ret = DFB_INCOMPLETE;
635 +
636 + return ret;
637 +}
638 +
639 +static DFBResult
640 +IDirectFBImageProvider_PNG_SetRenderCallback( IDirectFBImageProvider *thiz,
641 + DIRenderCallback callback,
642 + void *context )
643 +{
644 + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG)
645 +
646 + data->render_callback = callback;
647 + data->render_callback_context = context;
648 +
649 + return DFB_OK;
650 +}
651 +
652 +static DFBResult
653 +IDirectFBImageProvider_PNG_GetSurfaceDescription( IDirectFBImageProvider *thiz,
654 + DFBSurfaceDescription *dsc )
655 +{
656 + DFBSurfacePixelFormat primary_format = dfb_primary_layer_pixelformat();
657 +
658 + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG)
659 +
660 + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
661 + dsc->width = data->width;
662 + dsc->height = data->height;
663 +
664 + if (data->color_type & PNG_COLOR_MASK_ALPHA)
665 + dsc->pixelformat = DFB_PIXELFORMAT_HAS_ALPHA(primary_format) ? primary_format : DSPF_ARGB;
666 + else
667 + dsc->pixelformat = primary_format;
668 +
669 + if (data->color_type == PNG_COLOR_TYPE_PALETTE) {
670 + dsc->flags |= DSDESC_PALETTE;
671 +
672 + dsc->palette.entries = data->colors; /* FIXME */
673 + dsc->palette.size = 256;
674 + }
675 +
676 + return DFB_OK;
677 +}
678 +
679 +static DFBResult
680 +IDirectFBImageProvider_PNG_GetImageDescription( IDirectFBImageProvider *thiz,
681 + DFBImageDescription *dsc )
682 +{
683 + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_PNG)
684 +
685 + if (!dsc)
686 + return DFB_INVARG;
687 +
688 + dsc->caps = DICAPS_NONE;
689 +
690 + if (data->color_type & PNG_COLOR_MASK_ALPHA)
691 + dsc->caps |= DICAPS_ALPHACHANNEL;
692 +
693 + if (data->color_keyed) {
694 + dsc->caps |= DICAPS_COLORKEY;
695 +
696 + dsc->colorkey_r = (data->color_key & 0xff0000) >> 16;
697 + dsc->colorkey_g = (data->color_key & 0x00ff00) >> 8;
698 + dsc->colorkey_b = (data->color_key & 0x0000ff);
699 + }
700 +
701 + return DFB_OK;
702 +}
703 +
704 +/**********************************************************************************************************************/
705 +
706 +#define MAXCOLORMAPSIZE 256
707 +
708 +static int SortColors (const void *a, const void *b)
709 +{
710 + return (*((const u8 *) a) - *((const u8 *) b));
711 +}
712 +
713 +/* looks for a color that is not in the colormap and ideally not
714 + even close to the colors used in the colormap */
715 +static u32 FindColorKey( int n_colors, u8 *cmap )
716 +{
717 + u32 color = 0xFF000000;
718 + u8 csort[n_colors];
719 + int i, j, index, d;
720 +
721 + if (n_colors < 1)
722 + return color;
723 +
724 + for (i = 0; i < 3; i++) {
725 + direct_memcpy( csort, cmap + (n_colors * i), n_colors );
726 + qsort( csort, n_colors, 1, SortColors );
727 +
728 + for (j = 1, index = 0, d = 0; j < n_colors; j++) {
729 + if (csort[j] - csort[j-1] > d) {
730 + d = csort[j] - csort[j-1];
731 + index = j;
732 + }
733 + }
734 + if ((csort[0] - 0x0) > d) {
735 + d = csort[0] - 0x0;
736 + index = n_colors;
737 + }
738 + if (0xFF - (csort[n_colors - 1]) > d) {
739 + index = n_colors + 1;
740 + }
741 +
742 + if (index < n_colors)
743 + csort[0] = csort[index] - (d/2);
744 + else if (index == n_colors)
745 + csort[0] = 0x0;
746 + else
747 + csort[0] = 0xFF;
748 +
749 + color |= (csort[0] << (8 * (2 - i)));
750 + }
751 +
752 + return color;
753 +}
754 +
755 +/* Called at the start of the progressive load, once we have image info */
756 +static void
757 +png_info_callback( png_structp png_read_ptr,
758 + png_infop png_info_ptr )
759 +{
760 + int i;
761 + IDirectFBImageProvider_PNG_data *data;
762 +
763 + data = png_get_progressive_ptr( png_read_ptr );
764 +
765 + /* error stage? */
766 + if (data->stage < 0)
767 + return;
768 +
769 + /* set info stage */
770 + data->stage = STAGE_INFO;
771 +
772 + png_get_IHDR( data->png_ptr, data->info_ptr,
773 + &data->width, &data->height, &data->bpp, &data->color_type,
774 + NULL, NULL, NULL );
775 +
776 + if (png_get_valid( data->png_ptr, data->info_ptr, PNG_INFO_tRNS )) {
777 + png_bytep trans;
778 + png_color_16p trans_color;
779 + int num_trans;
780 +
781 + png_get_tRNS( data->png_ptr, data->info_ptr, &trans, &num_trans, &trans_color );
782 +
783 + data->color_keyed = true;
784 +
785 + /* generate color key based on palette... */
786 + if (data->color_type == PNG_COLOR_TYPE_PALETTE) {
787 + u32 key;
788 + png_colorp palette;
789 + int num_colors;
790 + u8 *cmap[3];
791 +
792 + png_get_PLTE( data->png_ptr, data->info_ptr, &palette, &num_colors );
793 + num_colors = MIN( MAXCOLORMAPSIZE, num_colors );
794 + cmap[0] = alloca (num_colors);
795 + cmap[1] = alloca (num_colors);
796 + cmap[2] = alloca (num_colors);
797 +
798 + for (i=0; i<num_colors; i++) {
799 + cmap[0][i] = palette[i].red;
800 + cmap[1][i] = palette[i].green;
801 + cmap[2][i] = palette[i].blue;
802 + }
803 +
804 + key = FindColorKey( num_colors, &cmap[0][0] );
805 +
806 + for (i=0; i<num_trans; i++) {
807 + if (!trans[i]) {
808 + palette[i].red = (key & 0xff0000) >> 16;
809 + palette[i].green = (key & 0x00ff00) >> 8;
810 + palette[i].blue = (key & 0x0000ff);
811 + }
812 + }
813 +
814 + data->color_key = key;
815 + }
816 + else {
817 + /* ...or based on trans rgb value */
818 + data->color_key = (((trans_color->red & 0xff00) << 8) |
819 + ((trans_color->green & 0xff00)) |
820 + ((trans_color->blue & 0xff00) >> 8));
821 + }
822 + }
823 +
824 + switch (data->color_type) {
825 + case PNG_COLOR_TYPE_PALETTE: {
826 + png_colorp palette = data->info_ptr->palette;
827 + png_bytep trans = data->info_ptr->trans;
828 + int num_trans = data->info_ptr->num_trans;
829 + int num_colors = MIN( MAXCOLORMAPSIZE, data->info_ptr->num_palette );
830 +
831 + for (i=0; i<num_colors; i++) {
832 + data->colors[i].a = (i < num_trans) ? trans[i] : 0xff;
833 + data->colors[i].r = palette[i].red;
834 + data->colors[i].g = palette[i].green;
835 + data->colors[i].b = palette[i].blue;
836 +
837 + data->palette[i] = PIXEL_ARGB( data->colors[i].a,
838 + data->colors[i].r,
839 + data->colors[i].g,
840 + data->colors[i].b );
841 + }
842 +
843 + data->pitch = (data->width + 7) & ~7;
844 + break;
845 + }
846 +
847 + case PNG_COLOR_TYPE_GRAY:
848 + data->pitch = data->width;
849 +
850 + if (data->bpp == 16)
851 + png_set_strip_16( data->png_ptr );
852 +
853 + break;
854 +
855 + case PNG_COLOR_TYPE_GRAY_ALPHA:
856 + png_set_gray_to_rgb( data->png_ptr );
857 + /* fall through */
858 +
859 + default:
860 + data->pitch = data->width * 4;
861 +
862 + if (data->bpp == 16)
863 + png_set_strip_16( data->png_ptr );
864 +
865 +#ifdef WORDS_BIGENDIAN
866 + if (!(data->color_type & PNG_COLOR_MASK_ALPHA))
867 + png_set_filler( data->png_ptr, 0xFF, PNG_FILLER_BEFORE );
868 +
869 + png_set_swap_alpha( data->png_ptr );
870 +#else
871 + if (!(data->color_type & PNG_COLOR_MASK_ALPHA))
872 + png_set_filler( data->png_ptr, 0xFF, PNG_FILLER_AFTER );
873 +
874 + png_set_bgr( data->png_ptr );
875 +#endif
876 + break;
877 + }
878 +
879 + png_set_interlace_handling( data->png_ptr );
880 +
881 + /* Update the info to reflect our transformations */
882 + png_read_update_info( data->png_ptr, data->info_ptr );
883 +}
884 +
885 +/* Called for each row; note that you will get duplicate row numbers
886 + for interlaced PNGs */
887 +static void
888 +png_row_callback( png_structp png_read_ptr,
889 + png_bytep new_row,
890 + png_uint_32 row_num,
891 + int pass_num )
892 +{
893 + IDirectFBImageProvider_PNG_data *data;
894 +
895 + data = png_get_progressive_ptr( png_read_ptr );
896 +
897 + /* error stage? */
898 + if (data->stage < 0)
899 + return;
900 +
901 + /* set image decoding stage */
902 + data->stage = STAGE_IMAGE;
903 +
904 + /* check image data pointer */
905 + if (!data->image) {
906 + // FIXME: allocates four additional bytes because the scaling functions
907 + // in src/misc/gfx_util.c have an off-by-one bug which causes
908 + // segfaults on darwin/osx (not on linux)
909 + int size = data->pitch * data->height + 4;
910 +
911 + /* allocate image data */
912 + data->image = D_CALLOC( 1, size );
913 + if (!data->image) {
914 + D_ERROR("DirectFB/ImageProvider_PNG: Could not "
915 + "allocate %d bytes of system memory!\n", size);
916 +
917 + /* set error stage */
918 + data->stage = STAGE_ERROR;
919 +
920 + return;
921 + }
922 + }
923 +
924 + /* write to image data */
925 + png_progressive_combine_row( data->png_ptr, (png_bytep) (data->image +
926 + row_num * data->pitch), new_row );
927 +
928 + /* increase row counter, FIXME: interlaced? */
929 + data->rows++;
930 +
931 + if (data->render_callback) {
932 + DIRenderCallbackResult r;
933 + DFBRectangle rect = { 0, row_num, data->width, 1 };
934 +
935 + r = data->render_callback( &rect, data->render_callback_context );
936 + if (r != DIRCR_OK)
937 + data->stage = STAGE_ABORT;
938 + }
939 +}
940 +
941 +/* Called after reading the entire image */
942 +static void
943 +png_end_callback (png_structp png_read_ptr,
944 + png_infop png_info_ptr)
945 +{
946 + IDirectFBImageProvider_PNG_data *data;
947 +
948 + data = png_get_progressive_ptr( png_read_ptr );
949 +
950 + /* error stage? */
951 + if (data->stage < 0)
952 + return;
953 +
954 + /* set end stage */
955 + data->stage = STAGE_END;
956 +}
957 +
958 +/* Pipes data into libpng until stage is different from the one specified. */
959 +static DFBResult
960 +push_data_until_stage (IDirectFBImageProvider_PNG_data *data,
961 + int stage,
962 + int buffer_size)
963 +{
964 + DFBResult ret;
965 + IDirectFBDataBuffer *buffer = data->buffer;
966 +
967 + while (data->stage < stage) {
968 + unsigned int len;
969 + unsigned char buf[buffer_size];
970 +
971 + if (data->stage < 0)
972 + return DFB_FAILURE;
973 +
974 + while (buffer->HasData( buffer ) == DFB_OK) {
975 + D_DEBUG( "ImageProvider/PNG: Retrieving data (up to %d bytes)...\n", buffer_size );
976 +
977 + ret = buffer->GetData( buffer, buffer_size, buf, &len );
978 + if (ret)
979 + return ret;
980 +
981 + D_DEBUG( "ImageProvider/PNG: Got %d bytes...\n", len );
982 +
983 + png_process_data( data->png_ptr, data->info_ptr, buf, len );
984 +
985 + D_DEBUG( "ImageProvider/PNG: ...processed %d bytes.\n", len );
986 +
987 + /* are we there yet? */
988 + if (data->stage < 0 || data->stage >= stage) {
989 + switch (data->stage) {
990 + case STAGE_ABORT: return DFB_INTERRUPTED;
991 + case STAGE_ERROR: return DFB_FAILURE;
992 + default: return DFB_OK;
993 + }
994 + }
995 + }
996 +
997 + D_DEBUG( "ImageProvider/PNG: Waiting for data...\n" );
998 +
999 + if (buffer->WaitForData( buffer, 1 ) == DFB_EOF)
1000 + return DFB_FAILURE;
1001 + }
1002 +
1003 + return DFB_OK;
1004 +}
1005 diff -Naur DirectFB-1.2.10/tools/directfb-csource.c DirectFB-1.2.10-magellan/tools/directfb-csource.c
1006 --- DirectFB-1.2.10/tools/directfb-csource.c 2009-08-27 21:54:18.000000000 +0200
1007 +++ DirectFB-1.2.10-magellan/tools/directfb-csource.c 2011-03-12 00:17:16.000000000 +0100
1008 @@ -300,7 +300,7 @@
1009 if (!png_ptr)
1010 goto cleanup;
1011
1012 - if (setjmp (png_ptr->jmpbuf)) {
1013 + if (setjmp (png_jmpbuf (png_ptr))) {
1014 if (desc->preallocated[0].data) {
1015 free (desc->preallocated[0].data);
1016 desc->preallocated[0].data = NULL;
1017 @@ -367,17 +367,22 @@
1018 }
1019
1020 switch (src_format) {
1021 - case DSPF_LUT8:
1022 - if (info_ptr->num_palette) {
1023 + case DSPF_LUT8: {
1024 + png_colorp png_palette;
1025 + int num_palette;
1026 +
1027 + png_get_PLTE( png_ptr, info_ptr, &png_palette, &num_palette );
1028 +
1029 + if (num_palette) {
1030 png_byte *alpha;
1031 int i, num;
1032
1033 - *palette_size = MIN (info_ptr->num_palette, 256);
1034 + *palette_size = MIN (num_palette, 256);
1035 for (i = 0; i < *palette_size; i++) {
1036 palette[i].a = 0xFF;
1037 - palette[i].r = info_ptr->palette[i].red;
1038 - palette[i].g = info_ptr->palette[i].green;
1039 - palette[i].b = info_ptr->palette[i].blue;
1040 + palette[i].r = png_palette[i].red;
1041 + palette[i].g = png_palette[i].green;
1042 + palette[i].b = png_palette[i].blue;
1043 }
1044 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
1045 png_get_tRNS (png_ptr, info_ptr, &alpha, &num, NULL);
1046 @@ -386,6 +391,7 @@
1047 }
1048 }
1049 break;
1050 + }
1051 case DSPF_RGB32:
1052 png_set_filler (png_ptr, 0xFF,
1053 #ifdef WORDS_BIGENDIAN
1054 diff -Naur DirectFB-1.2.10/tools/directfb-csource.c~ DirectFB-1.2.10-magellan/tools/directfb-csource.c~
1055 --- DirectFB-1.2.10/tools/directfb-csource.c~ 1970-01-01 01:00:00.000000000 +0100
1056 +++ DirectFB-1.2.10-magellan/tools/directfb-csource.c~ 2011-03-12 00:17:16.000000000 +0100
1057 @@ -0,0 +1,856 @@
1058 +/*
1059 + (c) Copyright 2001-2008 The world wide DirectFB Open Source Community (directfb.org)
1060 + (c) Copyright 2000-2004 Convergence (integrated media) GmbH
1061 +
1062 + All rights reserved.
1063 +
1064 + Written by Denis Oliver Kropp <dok@directfb.org>,
1065 + Andreas Hundt <andi@fischlustig.de>,
1066 + Sven Neumann <neo@directfb.org>,
1067 + Ville Syrjälä <syrjala@sci.fi> and
1068 + Claudio Ciccani <klan@users.sf.net>.
1069 +
1070 + directfb-csource is based on gdk-pixbuf-csource, a GdkPixbuf
1071 + based image CSource generator Copyright (C) 1999, 2001 Tim Janik
1072 +
1073 + This library is free software; you can redistribute it and/or
1074 + modify it under the terms of the GNU Lesser General Public
1075 + License as published by the Free Software Foundation; either
1076 + version 2 of the License, or (at your option) any later version.
1077 +
1078 + This library is distributed in the hope that it will be useful,
1079 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1080 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1081 + Lesser General Public License for more details.
1082 +
1083 + You should have received a copy of the GNU Lesser General Public
1084 + License along with this library; if not, write to the
1085 + Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1086 + Boston, MA 02111-1307, USA.
1087 +*/
1088 +
1089 +#include <config.h>
1090 +
1091 +#include <stdio.h>
1092 +#include <stdlib.h>
1093 +#include <string.h>
1094 +#include <errno.h>
1095 +#include <assert.h>
1096 +
1097 +#include <sys/types.h>
1098 +#include <sys/stat.h>
1099 +
1100 +#include <png.h>
1101 +
1102 +#include <directfb.h>
1103 +
1104 +#include <direct/types.h>
1105 +#include <direct/util.h>
1106 +
1107 +#include <gfx/convert.h>
1108 +
1109 +
1110 +static struct {
1111 + DFBSurfacePixelFormat format;
1112 + const char *name;
1113 +} pixelformats[] = {
1114 + { DSPF_ARGB, "ARGB" },
1115 + { DSPF_ARGB1555, "ARGB1555" },
1116 + { DSPF_ARGB2554, "ARGB2554" },
1117 + { DSPF_ARGB4444, "ARGB4444" },
1118 + { DSPF_RGB32, "RGB32" },
1119 + { DSPF_RGB24, "RGB24" },
1120 + { DSPF_RGB16, "RGB16" },
1121 + { DSPF_RGB332, "RGB332" },
1122 + { DSPF_A8, "A8" },
1123 + { DSPF_LUT8, "LUT8" }
1124 +};
1125 +static int n_pixelformats = D_ARRAY_SIZE( pixelformats );
1126 +
1127 +
1128 +static void print_usage (const char *prg_name);
1129 +static DFBResult load_image (const char *filename,
1130 + DFBSurfaceDescription *desc,
1131 + DFBColor *palette,
1132 + int *palette_size,
1133 + DFBSurfacePixelFormat rgbformat);
1134 +static DFBResult merge_images (DFBSurfaceDescription *images,
1135 + int num_images,
1136 + DFBSurfaceDescription *dest,
1137 + DFBRectangle *rectangles);
1138 +static DFBResult dump_raw_data (const char *name,
1139 + const unsigned char *data,
1140 + unsigned int len);
1141 +static DFBResult dump_image (const char *name,
1142 + DFBSurfaceDescription *desc,
1143 + DFBColor *palette,
1144 + int palette_size);
1145 +static DFBResult dump_rectangles (const char *name,
1146 + DFBRectangle *rectangles,
1147 + const char **names,
1148 + int num_rects);
1149 +static char * variable_name (const char *name);
1150 +static char * base_name (const char *name);
1151 +
1152 +
1153 +int main (int argc,
1154 + const char *argv[])
1155 +{
1156 + DFBSurfaceDescription desc = { flags: 0 };
1157 + DFBSurfacePixelFormat format = DSPF_UNKNOWN;
1158 + DFBSurfacePixelFormat rgbformat = DSPF_UNKNOWN;
1159 + DFBColor palette[256];
1160 +
1161 + const char *filename[argc];
1162 + const char *name = NULL;
1163 + int palette_size = 0;
1164 + int num_images = 0;
1165 + int i, n;
1166 + int rawmode = 0;
1167 +
1168 + /* parse command line */
1169 +
1170 + for (n = 1; n < argc; n++) {
1171 + if (strncmp (argv[n], "--", 2) == 0) {
1172 +
1173 + const char *arg = argv[n] + 2;
1174 +
1175 + if (strcmp (arg, "help") == 0) {
1176 + print_usage (argv[0]);
1177 + return EXIT_SUCCESS;
1178 + }
1179 + if (strcmp (arg, "version") == 0) {
1180 + fprintf (stderr, "directfb-csource version %s\n",
1181 + DIRECTFB_VERSION);
1182 + return EXIT_SUCCESS;
1183 + }
1184 + if (strcmp (arg, "raw") == 0) {
1185 + rawmode = 1;
1186 + continue;
1187 + }
1188 + if (strncmp (arg, "format=", 7) == 0 && !format) {
1189 + for (i = 0; i < n_pixelformats && !format; i++)
1190 + if (!strcasecmp (pixelformats[i].name, arg + 7))
1191 + format = pixelformats[i].format;
1192 + if (format)
1193 + continue;
1194 + }
1195 + if (strncmp (arg, "rgbformat=", 10) == 0 && !rgbformat) {
1196 + for (i = 0; i < n_pixelformats && !rgbformat; i++)
1197 + if (!strcasecmp (pixelformats[i].name, arg + 10))
1198 + rgbformat = pixelformats[i].format;
1199 + if (rgbformat)
1200 + continue;
1201 + }
1202 + if (strncmp (arg, "name=", 5) == 0 && !name) {
1203 + name = arg + 5;
1204 + if (*name)
1205 + continue;
1206 + }
1207 +
1208 + print_usage (argv[0]);
1209 + return EXIT_FAILURE;
1210 + }
1211 +
1212 + filename[num_images++] = argv[n];
1213 + }
1214 +
1215 + /* check parameters */
1216 +
1217 + if (! num_images) {
1218 + print_usage (argv[0]);
1219 + return EXIT_FAILURE;
1220 + }
1221 +
1222 + if (num_images > 1 && rawmode) {
1223 + fprintf (stderr,
1224 + "Multiple input files not allowed in raw mode.\n");
1225 + return EXIT_FAILURE;
1226 + }
1227 +
1228 + if (num_images > 1 && !name) {
1229 + fprintf (stderr,
1230 + "You must specify a variable name when using multiple images.\n");
1231 + return EXIT_FAILURE;
1232 + }
1233 +
1234 + /* load the first image */
1235 +
1236 + if (rawmode) {
1237 +
1238 + struct stat statbuf;
1239 + if (0 == stat(filename[0], &statbuf))
1240 + {
1241 + FILE *f;
1242 + unsigned char *data = alloca(statbuf.st_size);
1243 + memset(data, 0, statbuf.st_size);
1244 +
1245 + f = fopen(filename[0], "r");
1246 + if (f)
1247 + {
1248 + fread(data, statbuf.st_size, 1, f);
1249 + fclose(f);
1250 + }
1251 +
1252 + return dump_raw_data(name ? : strrchr (filename[0], '/') ? : filename[0],
1253 + data, statbuf.st_size);
1254 + }
1255 +
1256 + }
1257 + else {
1258 + if (format) {
1259 + desc.flags = DSDESC_PIXELFORMAT;
1260 + desc.pixelformat = format;
1261 + }
1262 +
1263 + if (load_image (filename[0], &desc, palette, &palette_size, rgbformat) != DFB_OK)
1264 + return EXIT_FAILURE;
1265 +
1266 + /* dump it and quit if this is the only image on the command line */
1267 +
1268 + if (num_images == 1)
1269 + return dump_image (name ? : strrchr (filename[0], '/') ? : filename[0],
1270 + &desc, palette, palette_size);
1271 + }
1272 +
1273 + /* merge multiple images into one surface */
1274 + {
1275 + DFBSurfaceDescription image[num_images];
1276 + DFBRectangle rect[num_images];
1277 + DFBColor foo[256];
1278 + int foo_size;
1279 +
1280 + image[0] = desc;
1281 +
1282 + for (i = 1; i < num_images; i++) {
1283 + image[i].flags = DSDESC_PIXELFORMAT;
1284 + image[i].pixelformat = desc.pixelformat;
1285 +
1286 + if (load_image (filename[i],
1287 + image + i, foo, &foo_size, rgbformat) != DFB_OK)
1288 + return EXIT_FAILURE;
1289 + }
1290 +
1291 + if (merge_images (image, num_images, &desc, rect) != DFB_OK)
1292 + return EXIT_FAILURE;
1293 +
1294 + /* dump the rectangles, then the surface */
1295 +
1296 + if (dump_rectangles (name, rect, filename, num_images) != DFB_OK)
1297 + return EXIT_FAILURE;
1298 +
1299 + return dump_image (name, &desc, palette, palette_size);
1300 + }
1301 +}
1302 +
1303 +static void print_usage (const char *prg_name)
1304 +{
1305 + fprintf (stderr, "directfb-csource version %s\n\n", DIRECTFB_VERSION);
1306 + fprintf (stderr, "Usage: %s [options] <imagefile>\n", prg_name);
1307 + fprintf (stderr, " --name=<identifer> specifies variable name\n");
1308 + fprintf (stderr, " --format=<identifer> specifies surface format\n");
1309 + fprintf (stderr, " --rgbformat=<identifer> specifies format for non-alpha images\n");
1310 + fprintf (stderr, " --multi multiple images\n");
1311 + fprintf (stderr, " --raw dump a single file directly to header\n");
1312 + fprintf (stderr, " --help show this help message\n");
1313 + fprintf (stderr, " --version print version information\n");
1314 + fprintf (stderr, "\n");
1315 + fprintf (stderr, "See the directfb-csource(1) man-page for more information.\n");
1316 + fprintf (stderr, "\n");
1317 +}
1318 +
1319 +static DFBResult load_image (const char *filename,
1320 + DFBSurfaceDescription *desc,
1321 + DFBColor *palette,
1322 + int *palette_size,
1323 + DFBSurfacePixelFormat rgbformat)
1324 +{
1325 + DFBSurfacePixelFormat dest_format;
1326 + DFBSurfacePixelFormat src_format;
1327 + FILE *fp;
1328 + png_structp png_ptr = NULL;
1329 + png_infop info_ptr = NULL;
1330 + png_uint_32 width, height;
1331 + unsigned char *data = NULL;
1332 + int type;
1333 + char header[8];
1334 + int bytes, pitch;
1335 +
1336 + dest_format =
1337 + (desc->flags & DSDESC_PIXELFORMAT) ? desc->pixelformat : DSPF_UNKNOWN;
1338 +
1339 + desc->flags = 0;
1340 + desc->preallocated[0].data = NULL;
1341 +
1342 + if (!(fp = fopen (filename, "rb"))) {
1343 + fprintf (stderr, "Failed to open file '%s': %s.\n",
1344 + filename, strerror (errno));
1345 + goto cleanup;
1346 + }
1347 +
1348 + bytes = fread (header, 1, sizeof(header), fp);
1349 + if (png_sig_cmp ((unsigned char*) header, 0, bytes)) {
1350 + fprintf (stderr, "File '%s' doesn't seem to be a PNG image file.\n",
1351 + filename);
1352 + goto cleanup;
1353 + }
1354 +
1355 + png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
1356 + NULL, NULL, NULL);
1357 + if (!png_ptr)
1358 + goto cleanup;
1359 +
1360 + if (setjmp (png_jmpbuf (png_ptr))) {
1361 + if (desc->preallocated[0].data) {
1362 + free (desc->preallocated[0].data);
1363 + desc->preallocated[0].data = NULL;
1364 + }
1365 +
1366 + /* data might have been clobbered,
1367 + set it to NULL and leak instead of crashing */
1368 + data = NULL;
1369 +
1370 + goto cleanup;
1371 + }
1372 +
1373 + info_ptr = png_create_info_struct (png_ptr);
1374 + if (!info_ptr)
1375 + goto cleanup;
1376 +
1377 + png_init_io (png_ptr, fp);
1378 + png_set_sig_bytes (png_ptr, bytes);
1379 +
1380 + png_read_info (png_ptr, info_ptr);
1381 +
1382 + png_get_IHDR (png_ptr, info_ptr,
1383 + &width, &height, &bytes, &type, NULL, NULL, NULL);
1384 +
1385 + if (bytes == 16)
1386 + png_set_strip_16 (png_ptr);
1387 +
1388 +#ifdef WORDS_BIGENDIAN
1389 + png_set_swap_alpha (png_ptr);
1390 +#else
1391 + png_set_bgr (png_ptr);
1392 +#endif
1393 +
1394 + src_format = (type & PNG_COLOR_MASK_ALPHA) ? DSPF_ARGB : DSPF_RGB32;
1395 + switch (type) {
1396 + case PNG_COLOR_TYPE_GRAY:
1397 + if (dest_format == DSPF_A8) {
1398 + src_format = DSPF_A8;
1399 + break;
1400 + }
1401 + /* fallthru */
1402 + case PNG_COLOR_TYPE_GRAY_ALPHA:
1403 + png_set_gray_to_rgb (png_ptr);
1404 + if (rgbformat)
1405 + dest_format = rgbformat;
1406 + break;
1407 +
1408 + case PNG_COLOR_TYPE_PALETTE:
1409 + if (dest_format == DSPF_LUT8) {
1410 + src_format = DSPF_LUT8;
1411 + break;
1412 + }
1413 + png_set_palette_to_rgb (png_ptr);
1414 + /* fallthru */
1415 + case PNG_COLOR_TYPE_RGB:
1416 + if (rgbformat)
1417 + dest_format = rgbformat;
1418 + case PNG_COLOR_TYPE_RGB_ALPHA:
1419 + if (dest_format == DSPF_RGB24) {
1420 + png_set_strip_alpha (png_ptr);
1421 + src_format = DSPF_RGB24;
1422 + }
1423 + break;
1424 + }
1425 +
1426 + switch (src_format) {
1427 + case DSPF_LUT8: {
1428 + png_colorp png_palette;
1429 + int num_palette;
1430 +
1431 + png_get_PLTE( png_ptr, info_ptr, &png_palette, &num_palette );
1432 +
1433 + if (num_palette) {
1434 + png_byte *alpha;
1435 + int i, num;
1436 +
1437 + *palette_size = MIN (num_palette, 256);
1438 + for (i = 0; i < *palette_size; i++) {
1439 + palette[i].a = 0xFF;
1440 + palette[i].r = png_palette[i].red;
1441 + palette[i].g = png_palette[i].green;
1442 + palette[i].b = png_palette[i].blue;
1443 + }
1444 + if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
1445 + png_get_tRNS (png_ptr, info_ptr, &alpha, &num, NULL);
1446 + for (i = 0; i < MIN (num, *palette_size); i++)
1447 + palette[i].a = alpha[i];
1448 + }
1449 + }
1450 + break;
1451 + case DSPF_RGB32:
1452 + png_set_filler (png_ptr, 0xFF,
1453 +#ifdef WORDS_BIGENDIAN
1454 + PNG_FILLER_BEFORE
1455 +#else
1456 + PNG_FILLER_AFTER
1457 +#endif
1458 + );
1459 + break;
1460 + case DSPF_ARGB:
1461 + case DSPF_A8:
1462 + if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1463 + png_set_tRNS_to_alpha (png_ptr);
1464 + break;
1465 + default:
1466 + break;
1467 + }
1468 +
1469 + pitch = width * DFB_BYTES_PER_PIXEL (src_format);
1470 + if (pitch & 3)
1471 + pitch += 4 - (pitch & 3);
1472 +
1473 + data = malloc (height * pitch);
1474 + if (!data) {
1475 + fprintf (stderr, "Failed to allocate %ld bytes.\n", height * pitch);
1476 + goto cleanup;
1477 + }
1478 +
1479 + {
1480 + unsigned int i;
1481 + png_bytep bptrs[height];
1482 +
1483 + for (i = 0; i < height; i++)
1484 + bptrs[i] = data + i * pitch;
1485 +
1486 + png_read_image (png_ptr, bptrs);
1487 + }
1488 +
1489 + if (!dest_format)
1490 + dest_format = src_format;
1491 +
1492 + if (DFB_BYTES_PER_PIXEL(src_format) != DFB_BYTES_PER_PIXEL(dest_format)) {
1493 + unsigned char *s, *d, *dest;
1494 + int d_pitch, h;
1495 +
1496 + assert (DFB_BYTES_PER_PIXEL (src_format) == 4);
1497 +
1498 + d_pitch = width * DFB_BYTES_PER_PIXEL (dest_format);
1499 + if (d_pitch & 3)
1500 + d_pitch += 4 - (d_pitch & 3);
1501 +
1502 + dest = malloc (height * d_pitch);
1503 + if (!dest) {
1504 + fprintf (stderr, "Failed to allocate %ld bytes.\n",
1505 + height * d_pitch);
1506 + goto cleanup;
1507 + }
1508 +
1509 + h = height;
1510 + switch (dest_format) {
1511 + case DSPF_RGB16:
1512 + for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
1513 + dfb_argb_to_rgb16 ((u32 *) s, (u16 *) d, width);
1514 + break;
1515 + case DSPF_ARGB1555:
1516 + for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
1517 + dfb_argb_to_argb1555 ((u32 *) s, (u16 *) d, width);
1518 + break;
1519 + case DSPF_ARGB2554:
1520 + for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
1521 + dfb_argb_to_argb2554 ((u32 *) s, (u16 *) d, width);
1522 + break;
1523 + case DSPF_ARGB4444:
1524 + for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
1525 + dfb_argb_to_argb4444 ((u32 *) s, (u16 *) d, width);
1526 + break;
1527 + case DSPF_RGB332:
1528 + for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
1529 + dfb_argb_to_rgb332 ((u32 *) s, (u8 *) d, width);
1530 + break;
1531 + case DSPF_A8:
1532 + for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
1533 + dfb_argb_to_a8 ((u32 *) s, (u8 *) d, width);
1534 + break;
1535 + default:
1536 + fprintf (stderr,
1537 + "Sorry, unsupported format conversion.\n");
1538 + goto cleanup;
1539 + }
1540 +
1541 + free (data);
1542 + data = dest;
1543 + pitch = d_pitch;
1544 + }
1545 +
1546 + desc->flags = (DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |
1547 + DSDESC_PREALLOCATED);
1548 + desc->width = width;
1549 + desc->height = height;
1550 + desc->pixelformat = dest_format;
1551 + desc->preallocated[0].pitch = pitch;
1552 + desc->preallocated[0].data = data;
1553 +
1554 + data = NULL;
1555 +
1556 + cleanup:
1557 + if (fp)
1558 + fclose (fp);
1559 +
1560 + if (png_ptr)
1561 + png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
1562 +
1563 + if (data)
1564 + free (data);
1565 +
1566 + return ((desc->flags) ? DFB_OK : DFB_FAILURE);
1567 +}
1568 +
1569 +static DFBResult merge_images (DFBSurfaceDescription *images,
1570 + int num_images,
1571 + DFBSurfaceDescription *dest,
1572 + DFBRectangle *rectangles)
1573 +{
1574 + DFBSurfaceDescription *image = images;
1575 + DFBRectangle *rect = rectangles;
1576 + unsigned char *data;
1577 + int bpp;
1578 + int pitch, i;
1579 +
1580 + rect->x = 0;
1581 + rect->y = 0;
1582 + rect->w = image->width;
1583 + rect->h = image->height;
1584 +
1585 + dest->flags = (DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |
1586 + DSDESC_PREALLOCATED);
1587 + dest->pixelformat = image->pixelformat;
1588 +
1589 + bpp = DFB_BYTES_PER_PIXEL (dest->pixelformat);
1590 +
1591 + if (bpp == 1)
1592 + dest->width = (rect->w + 3) & ~3;
1593 + else
1594 + dest->width = rect->w;
1595 +
1596 + dest->height = rect->h;
1597 +
1598 + for (i = 1; i < num_images; i++) {
1599 + image++;
1600 + rect++;
1601 +
1602 + if (image->pixelformat != dest->pixelformat)
1603 + return DFB_INVARG;
1604 +
1605 + rect->x = dest->width;
1606 + rect->y = 0;
1607 + rect->w = image->width;
1608 + rect->h = image->height;
1609 +
1610 + if (bpp == 1)
1611 + dest->width += (rect->w + 3) & ~3;
1612 + else
1613 + dest->width += rect->w;
1614 +
1615 + if (dest->height < rect->h)
1616 + dest->height = rect->h;
1617 + }
1618 +
1619 + pitch = (dest->width * bpp + 3) &~ 3;
1620 + data = malloc (dest->height * pitch);
1621 + if (!data) {
1622 + fprintf (stderr, "Failed to allocate %ld bytes.\n",
1623 + (long) dest->height * pitch);
1624 + return DFB_FAILURE;
1625 + }
1626 +
1627 +
1628 + for (i = 0, image = images, rect = rectangles;
1629 + i < num_images;
1630 + i++, image++, rect++) {
1631 +
1632 + unsigned char *dest = data + rect->x * bpp;
1633 + unsigned char *src = image->preallocated[0].data;
1634 + int height = rect->h;
1635 +
1636 + do {
1637 + memcpy (dest, src, rect->w * bpp);
1638 + src += image->preallocated[0].pitch;
1639 + dest += pitch;
1640 + }
1641 + while (--height);
1642 + }
1643 +
1644 + dest->preallocated[0].pitch = pitch;
1645 + dest->preallocated[0].data = data;
1646 +
1647 + return DFB_OK;
1648 +}
1649 +
1650 +
1651 +typedef struct {
1652 + FILE *fp;
1653 + int pos;
1654 + bool pad;
1655 +} CSourceData;
1656 +
1657 +static inline void save_uchar (CSourceData *csource,
1658 + unsigned char d)
1659 +{
1660 + if (csource->pos > 70) {
1661 + fprintf (csource->fp, "\"\n \"");
1662 +
1663 + csource->pos = 3;
1664 + csource->pad = false;
1665 + }
1666 + if (d < 33 || d > 126) {
1667 + fprintf (csource->fp, "\\%o", d);
1668 + csource->pos += 1 + 1 + (d > 7) + (d > 63);
1669 + csource->pad = d < 64;
1670 + return;
1671 + }
1672 + if (d == '\\') {
1673 + fprintf (csource->fp, "\\\\");
1674 + csource->pos += 2;
1675 + }
1676 + else if (d == '"') {
1677 + fprintf (csource->fp, "\\\"");
1678 + csource->pos += 2;
1679 + }
1680 + else if (csource->pad && d >= '0' && d <= '9') {
1681 + fprintf (csource->fp, "\"\"%c", d);
1682 + csource->pos += 3;
1683 + }
1684 + else {
1685 + fputc (d, csource->fp);
1686 + csource->pos += 1;
1687 + }
1688 + csource->pad = false;
1689 +
1690 + return;
1691 +}
1692 +
1693 +static void dump_data(CSourceData *csource,
1694 + const char *name,
1695 + const unsigned char *data,
1696 + unsigned int len)
1697 +{
1698 + fprintf (csource->fp,
1699 + "static const unsigned char %s_data[] =\n", name);
1700 + fprintf (csource->fp, " \"");
1701 +
1702 + csource->pos = 3;
1703 + do
1704 + save_uchar (csource, *data++);
1705 + while (--len);
1706 +
1707 + fprintf (csource->fp, "\";\n\n");
1708 +}
1709 +
1710 +static DFBResult dump_raw_data(const char *name,
1711 + const unsigned char *data,
1712 + unsigned int len)
1713 +{
1714 + CSourceData csource = { stdout, 0, 0 };
1715 + char *vname = variable_name (name);
1716 +
1717 + if (!data || !len)
1718 + return DFB_INVARG;
1719 +
1720 + fprintf (csource.fp,
1721 + "/* DirectFB raw data dump created by directfb-csource %s */\n\n",
1722 + DIRECTFB_VERSION);
1723 +
1724 + dump_data(&csource, vname, data, len);
1725 +
1726 + free (vname);
1727 +
1728 + return DFB_OK;
1729 +}
1730 +
1731 +
1732 +static DFBResult dump_image (const char *name,
1733 + DFBSurfaceDescription *desc,
1734 + DFBColor *palette,
1735 + int palette_size)
1736 +{
1737 + CSourceData csource = { stdout, 0, 0 };
1738 + const char *format = NULL;
1739 + char *vname = variable_name (name);
1740 + unsigned char *data;
1741 + unsigned long len;
1742 + int i;
1743 +
1744 + if (desc &&
1745 + desc->flags != (DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |
1746 + DSDESC_PREALLOCATED))
1747 + return DFB_INVARG;
1748 +
1749 + for (i = 0; i < n_pixelformats && !format; i++)
1750 + if (pixelformats[i].format == desc->pixelformat)
1751 + format = pixelformats[i].name;
1752 +
1753 + if (!format)
1754 + return DFB_INVARG;
1755 +
1756 + data = (unsigned char *) desc->preallocated[0].data;
1757 + len = desc->height * desc->preallocated[0].pitch;
1758 +
1759 + if (!len)
1760 + return DFB_INVARG;
1761 +
1762 + /* dump comment */
1763 + fprintf (csource.fp,
1764 + "/* DirectFB surface dump created by directfb-csource %s */\n\n",
1765 + DIRECTFB_VERSION);
1766 +
1767 + /* dump data */
1768 + dump_data(&csource, vname, data, len);
1769 +
1770 + /* dump palette */
1771 + if (palette_size > 0) {
1772 + fprintf (csource.fp,
1773 + "static const DFBColor %s_palette[%d] = {\n", vname, palette_size);
1774 + for (i = 0; i < palette_size; i++)
1775 + fprintf (csource.fp,
1776 + " { 0x%02x, 0x%02x, 0x%02x, 0x%02x }%c\n",
1777 + palette[i].a, palette[i].r, palette[i].g, palette[i].b,
1778 + i+1 < palette_size ? ',' : ' ');
1779 + fprintf (csource.fp, "};\n\n");
1780 + }
1781 +
1782 + /* dump description */
1783 + fprintf (csource.fp,
1784 + "static const DFBSurfaceDescription %s_desc = {\n", vname);
1785 + fprintf (csource.fp,
1786 + " flags : DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |\n"
1787 + " DSDESC_PREALLOCATED");
1788 + if (palette_size > 0)
1789 + fprintf (csource.fp, " | DSDESC_PALETTE");
1790 + fprintf (csource.fp, ",\n");
1791 + fprintf (csource.fp,
1792 + " width : %d,\n", desc->width);
1793 + fprintf (csource.fp,
1794 + " height : %d,\n", desc->height);
1795 + fprintf (csource.fp,
1796 + " pixelformat : DSPF_%s,\n", format);
1797 + fprintf (csource.fp,
1798 + " preallocated : {{ data : (void *) %s_data,\n", vname);
1799 + fprintf (csource.fp,
1800 + " pitch : %d }}", desc->preallocated[0].pitch);
1801 + if (palette_size > 0) {
1802 + fprintf (csource.fp, ",\n");
1803 + fprintf (csource.fp,
1804 + " palette : { entries : %s_palette,\n", vname);
1805 + fprintf (csource.fp,
1806 + " size : %d }", palette_size);
1807 + }
1808 + fprintf (csource.fp, "\n};\n\n");
1809 +
1810 + free (vname);
1811 +
1812 + return DFB_OK;
1813 +}
1814 +
1815 +static DFBResult dump_rectangles (const char *name,
1816 + DFBRectangle *rectangles,
1817 + const char **names,
1818 + int num_rects)
1819 +{
1820 + DFBRectangle *rect;
1821 + const char *blanks = " ";
1822 + char *vname = variable_name (name);
1823 + FILE *fp = stdout;
1824 + int len, i;
1825 +
1826 + if (num_rects < 1)
1827 + return DFB_INVARG;
1828 +
1829 + fprintf (fp,
1830 + "/* DirectFB multi-surface dump created by directfb-csource %s */\n\n",
1831 + DIRECTFB_VERSION);
1832 +
1833 + fprintf (fp,
1834 + "static const struct {\n"
1835 + " const char *name;\n"
1836 + " DFBRectangle rect;\n"
1837 + "} %s[] = {\n", vname);
1838 +
1839 + for (i = 0, len = 0; i < num_rects; i++)
1840 + len = MAX (len, strlen (names[i]));
1841 +
1842 + len = len + 4 - strlen (blanks);
1843 +
1844 + for (i = 0, rect = rectangles; i < num_rects; i++, rect++) {
1845 +
1846 + char *v = base_name (names[i]);
1847 +
1848 + if (i)
1849 + fprintf (fp, ",\n");
1850 +
1851 + if (len < 0) {
1852 + int l = fprintf (fp, " { \"%s\", ", v);
1853 +
1854 + fprintf (fp, blanks - len + l);
1855 + fprintf (fp, "{ x : %4d, y : %4d, w : %4d, h : %4d } }",
1856 + rect->x, rect->y, rect->w, rect->h);
1857 + }
1858 + else {
1859 + fprintf (fp,
1860 + " { \"%s\",\n"
1861 + " { x : %4d, y : %4d, w : %4d, h : %4d } }",
1862 + v, rect->x, rect->y, rect->w, rect->h);
1863 + }
1864 +
1865 + free (v);
1866 + }
1867 + fprintf (fp, "\n};\n\n");
1868 +
1869 + free (vname);
1870 +
1871 + return DFB_OK;
1872 +}
1873 +
1874 +static char *
1875 +variable_name (const char *name)
1876 +{
1877 + char *vname = strdup (name);
1878 + char *v = vname;
1879 +
1880 + while (DFB_TRUE) {
1881 + switch (*v) {
1882 + case 0:
1883 + return vname;
1884 + case 'a'...'z':
1885 + case 'A'...'Z':
1886 + case '0'...'9':
1887 + case '_':
1888 + break;
1889 + default:
1890 + *v = '_';
1891 + }
1892 + v++;
1893 + }
1894 +}
1895 +
1896 +static char *
1897 +base_name (const char *name)
1898 +{
1899 + char *vname = strdup (name);
1900 + char *v = vname;
1901 +
1902 + while (DFB_TRUE) {
1903 + switch (*v) {
1904 + case '.':
1905 + *v = 0;
1906 + case 0:
1907 + return vname;
1908 + default:
1909 + break;
1910 + }
1911 + v++;
1912 + }
1913 +}
1914 diff -Naur DirectFB-1.2.10/tools/mkdfiff.c DirectFB-1.2.10-magellan/tools/mkdfiff.c
1915 --- DirectFB-1.2.10/tools/mkdfiff.c 2009-08-27 21:54:18.000000000 +0200
1916 +++ DirectFB-1.2.10-magellan/tools/mkdfiff.c 2011-03-12 00:17:49.000000000 +0100
1917 @@ -97,7 +97,7 @@
1918 if (!png_ptr)
1919 goto cleanup;
1920
1921 - if (setjmp (png_ptr->jmpbuf)) {
1922 + if (setjmp (png_jmpbuf (png_ptr))) {
1923 if (desc->preallocated[0].data) {
1924 free (desc->preallocated[0].data);
1925 desc->preallocated[0].data = NULL;