Subversion Repositories Kolibri OS

Rev

Rev 1897 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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