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