Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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