Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1304 - (hide annotations) (download)
Fri Mar 11 23:02:07 2011 UTC (13 years, 2 months ago) by niro
File size: 66940 byte(s)
fixed patch
1 niro 1303 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 niro 1304 +++ DirectFB-1.2.10-magellan/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c 2011-03-12 00:13:13.000000000 +0100
4 niro 1303 @@ -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 niro 1304 @@ -464,7 +465,7 @@
58 niro 1303
59     default:
60     D_ERROR( "ImageProvider/PNG: Unsupported indexed bit depth %d!\n",
61     - data->info_ptr->bit_depth );
62     + bit_depth );
63 niro 1304 }
64 niro 1303
65     dfb_scale_linear_32( image_argb, data->width, data->height,
66 niro 1304 @@ -630,16 +631,26 @@
67 niro 1303 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 niro 1304
96 niro 1303 for (i=0; i<num_colors; i++) {
97     cmap[0][i] = palette[i].red;
98 niro 1304 @@ -649,7 +660,7 @@
99 niro 1303
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 niro 1304 @@ -661,20 +672,23 @@
108 niro 1303 }
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 niro 1304 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 niro 1303 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 niro 1304 +++ DirectFB-1.2.10-magellan/tools/directfb-csource.c 2011-03-12 00:17:16.000000000 +0100
1008 niro 1303 @@ -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 niro 1304 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 niro 1303 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 niro 1304 +++ DirectFB-1.2.10-magellan/tools/mkdfiff.c 2011-03-12 00:17:49.000000000 +0100
1917 niro 1303 @@ -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;