~ubuntu-branches/ubuntu/karmic/fltk1.1/karmic

« back to all changes in this revision

Viewing changes to png/pngwtran.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2005-05-22 13:57:06 UTC
  • mfrom: (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050522135706-mchag24yf42lu7bu
Tags: 1.1.6-5
* Revert previous change, which seems to have been ineffective for some
  reason, in favor of commenting out the problematic Makefile rule
  altogether.  (Closes: #310151.)
* debian/control: Go back to specifying the URL as part of the
  description rather than via a non-standard field that doesn't seem to
  have caught on.  (Closes: #310240.)

Show diffs side-by-side

added added

removed removed

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