Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1303 by niro, Fri Mar 11 22:30:57 2011 UTC revision 1304 by niro, Fri Mar 11 23:02:07 2011 UTC
# Line 1  Line 1 
1  diff -Naur DirectFB-1.2.10/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c DirectFB-1.2.10-magellan/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c  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  --- 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-11 23:43:18.000000000 +0100  +++ DirectFB-1.2.10-magellan/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c 2011-03-12 00:13:13.000000000 +0100
4  @@ -204,7 +204,7 @@  @@ -204,7 +204,7 @@
5        if (!data->png_ptr)        if (!data->png_ptr)
6             goto error;             goto error;
# Line 54  diff -Naur DirectFB-1.2.10/interfaces/ID Line 54  diff -Naur DirectFB-1.2.10/interfaces/ID
54                                 case 8:                                 case 8:
55                                      for (y=0; y<data->height; y++) {                                      for (y=0; y<data->height; y++) {
56                                           u8  *S = data->image + data->pitch * y;                                           u8  *S = data->image + data->pitch * y;
57  @@ -464,8 +465,8 @@  @@ -464,7 +465,7 @@
58    
59                                 default:                                 default:
60                                      D_ERROR( "ImageProvider/PNG: Unsupported indexed bit depth %d!\n",                                      D_ERROR( "ImageProvider/PNG: Unsupported indexed bit depth %d!\n",
61  -                                            data->info_ptr->bit_depth );  -                                            data->info_ptr->bit_depth );
 -                         }  
62  +                                            bit_depth );  +                                            bit_depth );
63  +                            }
64    
65                            dfb_scale_linear_32( image_argb, data->width, data->height,                            dfb_scale_linear_32( image_argb, data->width, data->height,
66                                                 lock.addr, lock.pitch, &rect, dst_surface, &clip );  @@ -630,16 +631,26 @@
 @@ -630,17 +631,26 @@  
67                      NULL, NULL, NULL );                      NULL, NULL, NULL );
68    
69        if (png_get_valid( data->png_ptr, data->info_ptr, PNG_INFO_tRNS )) {        if (png_get_valid( data->png_ptr, data->info_ptr, PNG_INFO_tRNS )) {
# Line 85  diff -Naur DirectFB-1.2.10/interfaces/ID Line 83  diff -Naur DirectFB-1.2.10/interfaces/ID
83  -               int        num_colors = MIN( MAXCOLORMAPSIZE,  -               int        num_colors = MIN( MAXCOLORMAPSIZE,
84  -                                            data->info_ptr->num_palette );  -                                            data->info_ptr->num_palette );
85  -               u8         cmap[3][num_colors];  -               u8         cmap[3][num_colors];
 -  
86  +               png_colorp palette;  +               png_colorp palette;
87  +               int        num_colors;  +               int        num_colors;
88  +               u8        *cmap[3];  +               u8        *cmap[3];
# Line 95  diff -Naur DirectFB-1.2.10/interfaces/ID Line 92  diff -Naur DirectFB-1.2.10/interfaces/ID
92  +               cmap[0] = alloca (num_colors);  +               cmap[0] = alloca (num_colors);
93  +               cmap[1] = alloca (num_colors);  +               cmap[1] = alloca (num_colors);
94  +               cmap[2] = alloca (num_colors);  +               cmap[2] = alloca (num_colors);
95    
96                  for (i=0; i<num_colors; i++) {                  for (i=0; i<num_colors; i++) {
97                       cmap[0][i] = palette[i].red;                       cmap[0][i] = palette[i].red;
98                       cmap[1][i] = palette[i].green;  @@ -649,7 +660,7 @@
 @@ -649,7 +659,7 @@  
99    
100                  key = FindColorKey( num_colors, &cmap[0][0] );                  key = FindColorKey( num_colors, &cmap[0][0] );
101    
# Line 107  diff -Naur DirectFB-1.2.10/interfaces/ID Line 104  diff -Naur DirectFB-1.2.10/interfaces/ID
104                       if (!trans[i]) {                       if (!trans[i]) {
105                            palette[i].red   = (key & 0xff0000) >> 16;                            palette[i].red   = (key & 0xff0000) >> 16;
106                            palette[i].green = (key & 0x00ff00) >>  8;                            palette[i].green = (key & 0x00ff00) >>  8;
107  @@ -661,20 +671,23 @@  @@ -661,20 +672,23 @@
108             }             }
109             else {             else {
110                  /* ...or based on trans rgb value */                  /* ...or based on trans rgb value */
# Line 140  diff -Naur DirectFB-1.2.10/interfaces/ID Line 137  diff -Naur DirectFB-1.2.10/interfaces/ID
137    
138                  for (i=0; i<num_colors; i++) {                  for (i=0; i<num_colors; i++) {
139                       data->colors[i].a = (i < num_trans) ? trans[i] : 0xff;                       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  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  --- 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-11 23:45:22.000000000 +0100  +++ DirectFB-1.2.10-magellan/tools/directfb-csource.c 2011-03-12 00:17:16.000000000 +0100
1008  @@ -300,7 +300,7 @@  @@ -300,7 +300,7 @@
1009        if (!png_ptr)        if (!png_ptr)
1010             goto cleanup;             goto cleanup;
# Line 189  diff -Naur DirectFB-1.2.10/tools/directf Line 1051  diff -Naur DirectFB-1.2.10/tools/directf
1051             case DSPF_RGB32:             case DSPF_RGB32:
1052                   png_set_filler (png_ptr, 0xFF,                   png_set_filler (png_ptr, 0xFF,
1053   #ifdef WORDS_BIGENDIAN   #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  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  --- 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-11 23:46:10.000000000 +0100  +++ DirectFB-1.2.10-magellan/tools/mkdfiff.c 2011-03-12 00:17:49.000000000 +0100
1917  @@ -97,7 +97,7 @@  @@ -97,7 +97,7 @@
1918        if (!png_ptr)        if (!png_ptr)
1919             goto cleanup;             goto cleanup;

Legend:
Removed from v.1303  
changed lines
  Added in v.1304