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; |
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 )) { |
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]; |
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 |
|
|
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 */ |
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; |
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; |