/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/png/pngwtran.c
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/png/pngwtran.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File MIME type: text/plain
File size: 17347 byte(s)
committing r3113 initial commit again...
1 william 31
2     /* pngwtran.c - transforms the data in a row for PNG writers
3     *
4     * Last changed in libpng 1.2.37 [June 4, 2009]
5     * Copyright (c) 1998-2009 Glenn Randers-Pehrson
6     * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7     * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8     *
9     * This code is released under the libpng license.
10     * For conditions of distribution and use, see the disclaimer
11     * and license in png.h
12     */
13    
14     #define PNG_INTERNAL
15     #include "png.h"
16     #ifdef PNG_WRITE_SUPPORTED
17    
18     /* Transform the data according to the user's wishes. The order of
19     * transformations is significant.
20     */
21     void /* PRIVATE */
22     png_do_write_transformations(png_structp png_ptr)
23     {
24     png_debug(1, "in png_do_write_transformations");
25    
26     if (png_ptr == NULL)
27     return;
28    
29     #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
30     if (png_ptr->transformations & PNG_USER_TRANSFORM)
31     if (png_ptr->write_user_transform_fn != NULL)
32     (*(png_ptr->write_user_transform_fn)) /* User write transform function */
33     (png_ptr, /* png_ptr */
34     &(png_ptr->row_info), /* row_info: */
35     /* png_uint_32 width; width of row */
36     /* png_uint_32 rowbytes; number of bytes in row */
37     /* png_byte color_type; color type of pixels */
38     /* png_byte bit_depth; bit depth of samples */
39     /* png_byte channels; number of channels (1-4) */
40     /* png_byte pixel_depth; bits per pixel (depth*channels) */
41     png_ptr->row_buf + 1); /* start of pixel data for row */
42     #endif
43     #if defined(PNG_WRITE_FILLER_SUPPORTED)
44     if (png_ptr->transformations & PNG_FILLER)
45     png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
46     png_ptr->flags);
47     #endif
48     #if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
49     if (png_ptr->transformations & PNG_PACKSWAP)
50     png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
51     #endif
52     #if defined(PNG_WRITE_PACK_SUPPORTED)
53     if (png_ptr->transformations & PNG_PACK)
54     png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
55     (png_uint_32)png_ptr->bit_depth);
56     #endif
57     #if defined(PNG_WRITE_SWAP_SUPPORTED)
58     if (png_ptr->transformations & PNG_SWAP_BYTES)
59     png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
60     #endif
61     #if defined(PNG_WRITE_SHIFT_SUPPORTED)
62     if (png_ptr->transformations & PNG_SHIFT)
63     png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
64     &(png_ptr->shift));
65     #endif
66     #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
67     if (png_ptr->transformations & PNG_SWAP_ALPHA)
68     png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
69     #endif
70     #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
71     if (png_ptr->transformations & PNG_INVERT_ALPHA)
72     png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
73     #endif
74     #if defined(PNG_WRITE_BGR_SUPPORTED)
75     if (png_ptr->transformations & PNG_BGR)
76     png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
77     #endif
78     #if defined(PNG_WRITE_INVERT_SUPPORTED)
79     if (png_ptr->transformations & PNG_INVERT_MONO)
80     png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
81     #endif
82     }
83    
84     #if defined(PNG_WRITE_PACK_SUPPORTED)
85     /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
86     * row_info bit depth should be 8 (one pixel per byte). The channels
87     * should be 1 (this only happens on grayscale and paletted images).
88     */
89     void /* PRIVATE */
90     png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
91     {
92     png_debug(1, "in png_do_pack");
93     if (row_info->bit_depth == 8 &&
94     #if defined(PNG_USELESS_TESTS_SUPPORTED)
95     row != NULL && row_info != NULL &&
96     #endif
97     row_info->channels == 1)
98     {
99     switch ((int)bit_depth)
100     {
101     case 1:
102     {
103     png_bytep sp, dp;
104     int mask, v;
105     png_uint_32 i;
106     png_uint_32 row_width = row_info->width;
107    
108     sp = row;
109     dp = row;
110     mask = 0x80;
111     v = 0;
112    
113     for (i = 0; i < row_width; i++)
114     {
115     if (*sp != 0)
116     v |= mask;
117     sp++;
118     if (mask > 1)
119     mask >>= 1;
120     else
121     {
122     mask = 0x80;
123     *dp = (png_byte)v;
124     dp++;
125     v = 0;
126     }
127     }
128     if (mask != 0x80)
129     *dp = (png_byte)v;
130     break;
131     }
132     case 2:
133     {
134     png_bytep sp, dp;
135     int shift, v;
136     png_uint_32 i;
137     png_uint_32 row_width = row_info->width;
138    
139     sp = row;
140     dp = row;
141     shift = 6;
142     v = 0;
143     for (i = 0; i < row_width; i++)
144     {
145     png_byte value;
146    
147     value = (png_byte)(*sp & 0x03);
148     v |= (value << shift);
149     if (shift == 0)
150     {
151     shift = 6;
152     *dp = (png_byte)v;
153     dp++;
154     v = 0;
155     }
156     else
157     shift -= 2;
158     sp++;
159     }
160     if (shift != 6)
161     *dp = (png_byte)v;
162     break;
163     }
164     case 4:
165     {
166     png_bytep sp, dp;
167     int shift, v;
168     png_uint_32 i;
169     png_uint_32 row_width = row_info->width;
170    
171     sp = row;
172     dp = row;
173     shift = 4;
174     v = 0;
175     for (i = 0; i < row_width; i++)
176     {
177     png_byte value;
178    
179     value = (png_byte)(*sp & 0x0f);
180     v |= (value << shift);
181    
182     if (shift == 0)
183     {
184     shift = 4;
185     *dp = (png_byte)v;
186     dp++;
187     v = 0;
188     }
189     else
190     shift -= 4;
191    
192     sp++;
193     }
194     if (shift != 4)
195     *dp = (png_byte)v;
196     break;
197     }
198     }
199     row_info->bit_depth = (png_byte)bit_depth;
200     row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
201     row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
202     row_info->width);
203     }
204     }
205     #endif
206    
207     #if defined(PNG_WRITE_SHIFT_SUPPORTED)
208     /* Shift pixel values to take advantage of whole range. Pass the
209     * true number of bits in bit_depth. The row should be packed
210     * according to row_info->bit_depth. Thus, if you had a row of
211     * bit depth 4, but the pixels only had values from 0 to 7, you
212     * would pass 3 as bit_depth, and this routine would translate the
213     * data to 0 to 15.
214     */
215     void /* PRIVATE */
216     png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
217     {
218     png_debug(1, "in png_do_shift");
219     #if defined(PNG_USELESS_TESTS_SUPPORTED)
220     if (row != NULL && row_info != NULL &&
221     #else
222     if (
223     #endif
224     row_info->color_type != PNG_COLOR_TYPE_PALETTE)
225     {
226     int shift_start[4], shift_dec[4];
227     int channels = 0;
228    
229     if (row_info->color_type & PNG_COLOR_MASK_COLOR)
230     {
231     shift_start[channels] = row_info->bit_depth - bit_depth->red;
232     shift_dec[channels] = bit_depth->red;
233     channels++;
234     shift_start[channels] = row_info->bit_depth - bit_depth->green;
235     shift_dec[channels] = bit_depth->green;
236     channels++;
237     shift_start[channels] = row_info->bit_depth - bit_depth->blue;
238     shift_dec[channels] = bit_depth->blue;
239     channels++;
240     }
241     else
242     {
243     shift_start[channels] = row_info->bit_depth - bit_depth->gray;
244     shift_dec[channels] = bit_depth->gray;
245     channels++;
246     }
247     if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
248     {
249     shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
250     shift_dec[channels] = bit_depth->alpha;
251     channels++;
252     }
253    
254     /* With low row depths, could only be grayscale, so one channel */
255     if (row_info->bit_depth < 8)
256     {
257     png_bytep bp = row;
258     png_uint_32 i;
259     png_byte mask;
260     png_uint_32 row_bytes = row_info->rowbytes;
261    
262     if (bit_depth->gray == 1 && row_info->bit_depth == 2)
263     mask = 0x55;
264     else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
265     mask = 0x11;
266     else
267     mask = 0xff;
268    
269     for (i = 0; i < row_bytes; i++, bp++)
270     {
271     png_uint_16 v;
272     int j;
273    
274     v = *bp;
275     *bp = 0;
276     for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
277     {
278     if (j > 0)
279     *bp |= (png_byte)((v << j) & 0xff);
280     else
281     *bp |= (png_byte)((v >> (-j)) & mask);
282     }
283     }
284     }
285     else if (row_info->bit_depth == 8)
286     {
287     png_bytep bp = row;
288     png_uint_32 i;
289     png_uint_32 istop = channels * row_info->width;
290    
291     for (i = 0; i < istop; i++, bp++)
292     {
293    
294     png_uint_16 v;
295     int j;
296     int c = (int)(i%channels);
297    
298     v = *bp;
299     *bp = 0;
300     for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
301     {
302     if (j > 0)
303     *bp |= (png_byte)((v << j) & 0xff);
304     else
305     *bp |= (png_byte)((v >> (-j)) & 0xff);
306     }
307     }
308     }
309     else
310     {
311     png_bytep bp;
312     png_uint_32 i;
313     png_uint_32 istop = channels * row_info->width;
314    
315     for (bp = row, i = 0; i < istop; i++)
316     {
317     int c = (int)(i%channels);
318     png_uint_16 value, v;
319     int j;
320    
321     v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
322     value = 0;
323     for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
324     {
325     if (j > 0)
326     value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
327     else
328     value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
329     }
330     *bp++ = (png_byte)(value >> 8);
331     *bp++ = (png_byte)(value & 0xff);
332     }
333     }
334     }
335     }
336     #endif
337    
338     #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
339     void /* PRIVATE */
340     png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
341     {
342     png_debug(1, "in png_do_write_swap_alpha");
343     #if defined(PNG_USELESS_TESTS_SUPPORTED)
344     if (row != NULL && row_info != NULL)
345     #endif
346     {
347     if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
348     {
349     /* This converts from ARGB to RGBA */
350     if (row_info->bit_depth == 8)
351     {
352     png_bytep sp, dp;
353     png_uint_32 i;
354     png_uint_32 row_width = row_info->width;
355     for (i = 0, sp = dp = row; i < row_width; i++)
356     {
357     png_byte save = *(sp++);
358     *(dp++) = *(sp++);
359     *(dp++) = *(sp++);
360     *(dp++) = *(sp++);
361     *(dp++) = save;
362     }
363     }
364     /* This converts from AARRGGBB to RRGGBBAA */
365     else
366     {
367     png_bytep sp, dp;
368     png_uint_32 i;
369     png_uint_32 row_width = row_info->width;
370    
371     for (i = 0, sp = dp = row; i < row_width; i++)
372     {
373     png_byte save[2];
374     save[0] = *(sp++);
375     save[1] = *(sp++);
376     *(dp++) = *(sp++);
377     *(dp++) = *(sp++);
378     *(dp++) = *(sp++);
379     *(dp++) = *(sp++);
380     *(dp++) = *(sp++);
381     *(dp++) = *(sp++);
382     *(dp++) = save[0];
383     *(dp++) = save[1];
384     }
385     }
386     }
387     else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
388     {
389     /* This converts from AG to GA */
390     if (row_info->bit_depth == 8)
391     {
392     png_bytep sp, dp;
393     png_uint_32 i;
394     png_uint_32 row_width = row_info->width;
395    
396     for (i = 0, sp = dp = row; i < row_width; i++)
397     {
398     png_byte save = *(sp++);
399     *(dp++) = *(sp++);
400     *(dp++) = save;
401     }
402     }
403     /* This converts from AAGG to GGAA */
404     else
405     {
406     png_bytep sp, dp;
407     png_uint_32 i;
408     png_uint_32 row_width = row_info->width;
409    
410     for (i = 0, sp = dp = row; i < row_width; i++)
411     {
412     png_byte save[2];
413     save[0] = *(sp++);
414     save[1] = *(sp++);
415     *(dp++) = *(sp++);
416     *(dp++) = *(sp++);
417     *(dp++) = save[0];
418     *(dp++) = save[1];
419     }
420     }
421     }
422     }
423     }
424     #endif
425    
426     #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
427     void /* PRIVATE */
428     png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
429     {
430     png_debug(1, "in png_do_write_invert_alpha");
431     #if defined(PNG_USELESS_TESTS_SUPPORTED)
432     if (row != NULL && row_info != NULL)
433     #endif
434     {
435     if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
436     {
437     /* This inverts the alpha channel in RGBA */
438     if (row_info->bit_depth == 8)
439     {
440     png_bytep sp, dp;
441     png_uint_32 i;
442     png_uint_32 row_width = row_info->width;
443     for (i = 0, sp = dp = row; i < row_width; i++)
444     {
445     /* Does nothing
446     *(dp++) = *(sp++);
447     *(dp++) = *(sp++);
448     *(dp++) = *(sp++);
449     */
450     sp+=3; dp = sp;
451     *(dp++) = (png_byte)(255 - *(sp++));
452     }
453     }
454     /* This inverts the alpha channel in RRGGBBAA */
455     else
456     {
457     png_bytep sp, dp;
458     png_uint_32 i;
459     png_uint_32 row_width = row_info->width;
460    
461     for (i = 0, sp = dp = row; i < row_width; i++)
462     {
463     /* Does nothing
464     *(dp++) = *(sp++);
465     *(dp++) = *(sp++);
466     *(dp++) = *(sp++);
467     *(dp++) = *(sp++);
468     *(dp++) = *(sp++);
469     *(dp++) = *(sp++);
470     */
471     sp+=6; dp = sp;
472     *(dp++) = (png_byte)(255 - *(sp++));
473     *(dp++) = (png_byte)(255 - *(sp++));
474     }
475     }
476     }
477     else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
478     {
479     /* This inverts the alpha channel in GA */
480     if (row_info->bit_depth == 8)
481     {
482     png_bytep sp, dp;
483     png_uint_32 i;
484     png_uint_32 row_width = row_info->width;
485    
486     for (i = 0, sp = dp = row; i < row_width; i++)
487     {
488     *(dp++) = *(sp++);
489     *(dp++) = (png_byte)(255 - *(sp++));
490     }
491     }
492     /* This inverts the alpha channel in GGAA */
493     else
494     {
495     png_bytep sp, dp;
496     png_uint_32 i;
497     png_uint_32 row_width = row_info->width;
498    
499     for (i = 0, sp = dp = row; i < row_width; i++)
500     {
501     /* Does nothing
502     *(dp++) = *(sp++);
503     *(dp++) = *(sp++);
504     */
505     sp+=2; dp = sp;
506     *(dp++) = (png_byte)(255 - *(sp++));
507     *(dp++) = (png_byte)(255 - *(sp++));
508     }
509     }
510     }
511     }
512     }
513     #endif
514    
515     #if defined(PNG_MNG_FEATURES_SUPPORTED)
516     /* Undoes intrapixel differencing */
517     void /* PRIVATE */
518     png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
519     {
520     png_debug(1, "in png_do_write_intrapixel");
521     if (
522     #if defined(PNG_USELESS_TESTS_SUPPORTED)
523     row != NULL && row_info != NULL &&
524     #endif
525     (row_info->color_type & PNG_COLOR_MASK_COLOR))
526     {
527     int bytes_per_pixel;
528     png_uint_32 row_width = row_info->width;
529     if (row_info->bit_depth == 8)
530     {
531     png_bytep rp;
532     png_uint_32 i;
533    
534     if (row_info->color_type == PNG_COLOR_TYPE_RGB)
535     bytes_per_pixel = 3;
536     else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
537     bytes_per_pixel = 4;
538     else
539     return;
540    
541     for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
542     {
543     *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
544     *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
545     }
546     }
547     else if (row_info->bit_depth == 16)
548     {
549     png_bytep rp;
550     png_uint_32 i;
551    
552     if (row_info->color_type == PNG_COLOR_TYPE_RGB)
553     bytes_per_pixel = 6;
554     else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
555     bytes_per_pixel = 8;
556     else
557     return;
558    
559     for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
560     {
561     png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
562     png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
563     png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
564     png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
565     png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
566     *(rp ) = (png_byte)((red >> 8) & 0xff);
567     *(rp+1) = (png_byte)(red & 0xff);
568     *(rp+4) = (png_byte)((blue >> 8) & 0xff);
569     *(rp+5) = (png_byte)(blue & 0xff);
570     }
571     }
572     }
573     }
574     #endif /* PNG_MNG_FEATURES_SUPPORTED */
575     #endif /* PNG_WRITE_SUPPORTED */

  ViewVC Help
Powered by ViewVC 1.1.22