1
2 #include "studiox_includes.h"
3 #include "image_reader.h"
4 #include "png.h"
5
6 png_structp png_instance;
7 png_infop png_info_ptr;
8
9 ///////////////////////////////////////////////////////////////////////////////
input_stream(unsigned char * data,int data_size)10 input_stream::input_stream(unsigned char* data, int data_size)
11 {
12 mpData = data;
13 mDataSize = data_size;
14 mReadSize = 0;
15 }
16
17 ///////////////////////////////////////////////////////////////////////////////
Read(void * pv,ULONG cb,ULONG * pcbRead)18 IFACEMETHODIMP input_stream::Read(void *pv, ULONG cb, ULONG *pcbRead)
19 {
20 if (mReadSize < mDataSize)
21 {
22 ULONG remain_size = mDataSize - mReadSize;
23
24 if (cb <= remain_size)
25 {
26 memcpy((void *)pv, (void *)(mpData + mReadSize), cb); /* Use case of memcpy is verified. */
27 mReadSize += cb;
28
29 if (pcbRead)
30 {
31 *pcbRead = cb;
32 }
33 }
34 else
35 {
36 memcpy((void *)pv, (void *)(mpData + mReadSize), remain_size); /* Use case of memcpy is verified. */
37 mReadSize += remain_size;
38
39 if (pcbRead)
40 {
41 *pcbRead = remain_size;
42 }
43 }
44 }
45
46 return 0;
47 }
48
png_reader()49 png_reader::png_reader() : image_reader()
50 {
51 mpRowPointers = NULL;
52 }
53
~png_reader()54 png_reader::~png_reader()
55 {
56 }
57
CheckImageHasAlphaChannel(CString & path)58 BOOL png_reader::CheckImageHasAlphaChannel(CString &path)
59 {
60 BOOL has_alpha = FALSE;
61 UCHAR signature[8];
62
63 FILE *file = _tfopen(path.GetBuffer(), _T("rb"));
64
65 if (!file)
66 {
67 return FALSE;
68 }
69
70 fread(signature, 1, 8, file);
71 if (png_sig_cmp(signature, 0, 8))
72 {
73 fclose(file);
74 return FALSE;
75 }
76
77 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
78 NULL, NULL, NULL);
79
80 if (!png_ptr)
81 {
82 fclose(file);
83 return FALSE;
84 }
85
86 png_infop info = png_create_info_struct(png_ptr);
87
88 if (!info)
89 {
90 fclose(file);
91 png_destroy_read_struct(&png_ptr, NULL, NULL);
92 return FALSE;
93 }
94
95 png_init_io(png_ptr, file);
96 png_set_sig_bytes(png_ptr, 8);
97 png_read_info(png_ptr, info);
98
99 int color_type, num_trans;
100
101 //get information from the info
102 if (png_get_IHDR(png_ptr, info, NULL, NULL, NULL, &color_type, NULL, NULL, NULL) == 0)
103 {
104 color_type = -1;
105 }
106
107 if (png_get_tRNS(png_ptr, info, NULL, &num_trans, NULL) == 0)
108 {
109 num_trans = 0;
110 }
111
112 switch (color_type)
113 {
114 case PNG_COLOR_TYPE_RGB_ALPHA:
115 case PNG_COLOR_TYPE_GRAY_ALPHA:
116 has_alpha = TRUE;
117 break;
118
119 case PNG_COLOR_TYPE_PALETTE:
120 case PNG_COLOR_TYPE_GRAY:
121 case PNG_COLOR_TYPE_RGB:
122
123 if (num_trans > 0)
124 {
125 has_alpha = TRUE;
126 }
127 break;
128 default:
129 break;
130 }
131
132 png_destroy_read_struct(&png_ptr, &info, NULL);
133 fclose(file);
134 return has_alpha;
135 }
136
137 ///////////////////////////////////////////////////////////////////////////////
ReadImage(CString & path,int frame_id)138 BOOL png_reader::ReadImage(CString &path, int frame_id)
139 {
140 UCHAR signature[8];
141
142 FILE *file = _tfopen(path.GetBuffer(), _T("rb"));
143
144 if (!file)
145 {
146 return FALSE;
147 }
148
149 fread(signature, 1, 8, file);
150 if (png_sig_cmp(signature, 0, 8))
151 {
152 fclose(file);
153 return FALSE;
154 }
155
156 m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
157 NULL, NULL, NULL);
158
159 if (!m_png)
160 {
161 fclose(file);
162 return FALSE;
163 }
164 png_instance = m_png;
165
166 m_info = png_create_info_struct(m_png);
167 if (!m_info)
168 {
169 fclose(file);
170 png_destroy_read_struct(&m_png, NULL, NULL);
171 return FALSE;
172 }
173
174 png_init_io(m_png, file);
175 png_set_sig_bytes(m_png, 8);
176 png_read_png(m_png, m_info, PNG_TRANSFORM_IDENTITY, NULL);
177 png_info_ptr = m_info;
178
179 png_uint_32 width, height;
180
181 // get information from the m_info
182 if (png_get_IHDR(m_png, m_info, &width, &height, NULL, NULL, NULL, NULL, NULL) != 0)
183 {
184 mpRowPointers = png_get_rows(m_png, m_info);
185
186 if (mpRowPointers)
187 {
188 ConfigureInternalFormat();
189 DoCompress(FALSE);
190 if (!FinalizeImage(width, height))
191 {
192 png_destroy_read_struct(&m_png, &m_info, NULL);
193 fclose(file);
194 return FALSE;
195 }
196 }
197 }
198
199 png_destroy_read_struct(&m_png, &m_info, NULL);
200 fclose(file);
201 return TRUE;
202 }
203
204 ///////////////////////////////////////////////////////////////////////////////
ReadImage(IStream * input_stream)205 BOOL png_reader::ReadImage(IStream *input_stream)
206 {
207 UCHAR signature[8];
208
209 input_stream->Read(signature, 8, NULL);
210
211 if (png_sig_cmp(signature, 0, 8))
212 {
213 return FALSE;
214 }
215
216 m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
217 NULL, NULL, NULL);
218
219 if (!m_png)
220 {
221 return FALSE;
222 }
223 png_instance = m_png;
224
225 m_info = png_create_info_struct(m_png);
226 if (!m_info)
227 {
228 png_destroy_read_struct(&m_png, NULL, NULL);
229 return FALSE;
230 }
231
232 // Set user-defined function for reading a PNG stream.
233 png_set_read_fn(m_png, input_stream, ReadDataFromIStream);
234
235 png_set_sig_bytes(m_png, 8);
236 png_read_png(m_png, m_info, PNG_TRANSFORM_IDENTITY, NULL);
237 png_info_ptr = m_info;
238
239 png_uint_32 width, height;
240
241 // get information from the m_info
242 if (png_get_IHDR(m_png, m_info, &width, &height, NULL, NULL, NULL, NULL, NULL) != 0)
243 {
244 mpRowPointers = png_get_rows(m_png, m_info);
245
246 if (mpRowPointers)
247 {
248 ConfigureInternalFormat();
249 DoCompress(FALSE);
250 if (!FinalizeImage(width, height))
251 {
252 png_destroy_read_struct(&m_png, &m_info, NULL);
253 return FALSE;
254 }
255 }
256 }
257
258 png_destroy_read_struct(&m_png, &m_info, NULL);
259 return TRUE;
260 }
261
262 ///////////////////////////////////////////////////////////////////////////////
ReadImage(unsigned char * data,int data_size)263 BOOL png_reader::ReadImage(unsigned char* data, int data_size)
264 {
265 input_stream inputstream(data, data_size);
266
267 return ReadImage((IStream *)&inputstream);
268 }
269
270 ///////////////////////////////////////////////////////////////////////////////
GetInputDataPtr(int row)271 UCHAR *png_reader::GetInputDataPtr(int row)
272 {
273 if (mpRowPointers)
274 {
275 return mpRowPointers[row];
276 }
277 return NULL;
278 }
279
280
281 // the data formats supported by the PNG decoder are not always
282 // formats that our image_reader understands, so we have to convert
283 // the odd formats to something we do understand
284
285 ///////////////////////////////////////////////////////////////////////////////
ReadPixel48(image_reader * reader,int Index,Pixel * Pixel)286 void png_reader::ReadPixel48(image_reader *reader, int Index, Pixel *Pixel)
287 {
288 const USHORT *pGet = (USHORT *)reader->mpGetData;
289 pGet += Index * 3;
290 Pixel->Red = *pGet++;
291 Pixel->Green = *pGet++;
292 Pixel->Blue = *pGet;
293
294 int num_trans;
295 png_color_16p trans_color;
296 if (png_get_tRNS(png_instance, png_info_ptr, NULL, &num_trans, &trans_color) == 0)
297 {
298 num_trans = 0;
299 trans_color = NULL;
300 }
301
302 if ((num_trans > 0) &&
303 (trans_color->red == Pixel->Red) &&
304 (trans_color->green == Pixel->Green) &&
305 (trans_color->blue == Pixel->Blue))
306 {
307 //Transparent
308 Pixel->Alpha = 0;
309 }
310 else
311 {
312 Pixel->Red &= 0xff;
313 Pixel->Green &= 0xff;
314 Pixel->Blue &= 0xff;
315 Pixel->Alpha = 0xff;
316 }
317 }
318
319 ///////////////////////////////////////////////////////////////////////////////
ReadPixel1(image_reader * reader,int Index,Pixel * put)320 void png_reader::ReadPixel1(image_reader *reader, int Index, Pixel *put)
321 {
322 UCHAR pal_index;
323 const GX_UBYTE *pGet = reader->mpGetData;
324
325 put->Red = put->Green = put->Blue = put->Alpha = 0;
326
327 pGet += (Index >> 3);
328 pal_index = *pGet;
329 pal_index >>= (7 - (Index & 0x07));
330 pal_index &= 0x01;
331
332 png_colorp palette;
333 int num_palette, num_trans;
334 png_bytep trans_alpha;
335 png_color_16p trans_color;
336
337 //get information from the png_ingo
338
339 if (png_get_PLTE(png_instance, png_info_ptr, &palette, &num_palette) == 0)
340 {
341 palette = NULL;
342 num_palette = 0;
343 }
344
345 if (png_get_tRNS(png_instance, png_info_ptr, &trans_alpha, &num_trans, &trans_color) == 0)
346 {
347 trans_alpha = NULL;
348 num_trans = 0;
349 trans_color = NULL;
350 }
351
352
353 if (palette)
354 {
355 //Palette
356 if ((num_trans > 0) && (trans_alpha[0] == pal_index))
357 {
358 put->Alpha = 0;
359 }
360 else
361 {
362 if (pal_index < num_palette)
363 {
364 put->Red = palette[pal_index].red;
365 put->Green = palette[pal_index].green;
366 put->Blue = palette[pal_index].blue;
367 }
368 put->Alpha = 0xff;
369 }
370 }
371 else
372 {
373 //Gray
374 if ((num_trans > 0) && (trans_color->gray == pal_index))
375 {
376 put->Alpha = 0;
377 }
378 else
379 {
380 pal_index *= 255;
381 put->Red = pal_index;
382 put->Green = pal_index;
383 put->Blue = pal_index;
384 put->Alpha = 0xff;
385 }
386 }
387
388 }
389 ///////////////////////////////////////////////////////////////////////////////
ReadPixel2(image_reader * reader,int Index,Pixel * put)390 void png_reader::ReadPixel2(image_reader *reader, int Index, Pixel *put)
391 {
392 UCHAR pal_index;
393 const GX_UBYTE *pGet = reader->mpGetData;
394
395 put->Red = put->Green = put->Blue = put->Alpha = 0;
396
397 pGet += (Index >> 2);
398 pal_index = *pGet;
399 pal_index >>= (3 - (Index & 0x03)) * 2;
400 pal_index &= 0x03;
401
402 png_colorp palette;
403 int num_palette, num_trans;
404 png_bytep trans_alpha;
405 png_color_16p trans_color;
406
407 //get information from the png_info
408 if (png_get_PLTE(png_instance, png_info_ptr, &palette, &num_palette) == 0)
409 {
410 palette = NULL;
411 num_palette = 0;
412 }
413
414 if (png_get_tRNS(png_instance, png_info_ptr, &trans_alpha, &num_trans, &trans_color) == 0)
415 {
416 trans_alpha = NULL;
417 num_trans = 0;
418 trans_color = NULL;
419 }
420
421 if (palette)
422 {
423 //Palette
424 if ((num_trans > 0) && (trans_alpha[0] == pal_index))
425 {
426 put->Alpha = 0;
427 }
428 else
429 {
430 if (pal_index < num_palette)
431 {
432 put->Red = palette[pal_index].red;
433 put->Green = palette[pal_index].green;
434 put->Blue = palette[pal_index].blue;
435 }
436 put->Alpha = 0xff;
437 }
438 }
439 else
440 {
441 //Gray
442 if ((num_trans > 0) && (trans_color->gray == pal_index))
443 {
444 put->Alpha = 0;
445 }
446 else
447 {
448 pal_index = pal_index * 255 / 3;
449 put->Red = pal_index;
450 put->Green = pal_index;
451 put->Blue = pal_index;
452 put->Alpha = 0xff;
453 }
454 }
455 }
456 ///////////////////////////////////////////////////////////////////////////////
ReadPixel4(image_reader * reader,int Index,Pixel * put)457 void png_reader::ReadPixel4(image_reader *reader, int Index, Pixel *put)
458 {
459 UCHAR pal_index;
460 const GX_UBYTE *pGet = reader->mpGetData;
461
462 put->Red = put->Green = put->Blue = put->Alpha = 0;
463
464 pGet += (Index >> 1);
465 pal_index = *pGet;
466 pal_index >>= (1 - (Index & 0x01)) * 4;
467 pal_index &= 0x0f;
468
469 png_colorp palette;
470 int num_palette, num_trans;
471 png_bytep trans_alpha;
472 png_color_16p trans_color;
473
474 // get information from the png_info
475 if (png_get_PLTE(png_instance, png_info_ptr, &palette, &num_palette) == 0)
476 {
477 palette = NULL;
478 num_palette = 0;
479 }
480
481 if (png_get_tRNS(png_instance, png_info_ptr, &trans_alpha, &num_trans, &trans_color) == 0)
482 {
483 trans_alpha = NULL;
484 num_trans = 0;
485 trans_color = NULL;
486 }
487
488 if (palette)
489 {
490 //Palette
491 if ((num_trans > 0) && (trans_alpha[0] == pal_index))
492 {
493 put->Alpha = 0;
494 }
495 else
496 {
497 if (pal_index < num_palette)
498 {
499 put->Red = palette[pal_index].red;
500 put->Green = palette[pal_index].green;
501 put->Blue = palette[pal_index].blue;
502 }
503 put->Alpha = 0xff;
504 }
505 }
506 else
507 {
508 //Gray
509
510 if ((num_trans > 0) && (trans_color->gray == pal_index))
511 {
512 put->Alpha = 0;
513 }
514 else
515 {
516 pal_index = pal_index * 255 / 15;
517 put->Red = pal_index;
518 put->Green = pal_index;
519 put->Blue = pal_index;
520 put->Alpha = 0xff;
521 }
522 }
523 }
524
525 ///////////////////////////////////////////////////////////////////////////////
ReadPixel8(image_reader * reader,int Index,Pixel * put)526 void png_reader::ReadPixel8(image_reader *reader, int Index, Pixel *put)
527 {
528 UCHAR pal_index;
529 const GX_UBYTE *pGet = reader->mpGetData;
530
531 put->Red = put->Green = put->Blue = put->Alpha = 0;
532
533 pGet += Index;
534 pal_index = *pGet;
535
536 int color_type, num_palette, num_trans;
537 png_colorp palette;
538 png_bytep trans_alpha;
539 png_color_16p trans_color;
540
541 //get information from the info
542 if (png_get_IHDR(png_instance, png_info_ptr, NULL, NULL, NULL, &color_type, NULL, NULL, NULL) == 0)
543 {
544 color_type = -1;
545 }
546
547
548 if (png_get_PLTE(png_instance, png_info_ptr, &palette, &num_palette) == 0)
549 {
550 palette = NULL;
551 num_palette = 0;
552 }
553
554 if (png_get_tRNS(png_instance, png_info_ptr, &trans_alpha, &num_trans, &trans_color) == 0)
555 {
556 trans_alpha = NULL;
557 num_trans = 0;
558 trans_color = NULL;
559 }
560
561 switch(color_type)
562 {
563 case 3: // indexed color
564 if (pal_index < num_palette)
565 {
566 put->Red = palette[pal_index].red;
567 put->Green = palette[pal_index].green;
568 put->Blue = palette[pal_index].blue;
569 }
570 if (pal_index < num_trans)
571 {
572 put->Alpha = trans_alpha[pal_index];
573 }
574 else
575 {
576 put->Alpha = 0xff;
577 }
578 break;
579
580 case 2: // TrueColor image data
581 if (pal_index < num_palette)
582 {
583 put->Red = palette[pal_index].red;
584 put->Green = palette[pal_index].green;
585 put->Blue = palette[pal_index].blue;
586 }
587 if ((num_trans > 0) && (trans_alpha[0] == pal_index))
588 {
589 put->Alpha = 0;
590 }
591 else
592 {
593 put->Alpha = 0xff;
594 }
595 break;
596
597 case 0: // grayscale
598 //Gray
599 if ((num_trans > 0) && (trans_color->gray == pal_index))
600 {
601 put->Alpha = 0;
602 }
603 else
604 {
605 put->Red = pal_index;
606 put->Green = pal_index;
607 put->Blue = pal_index;
608 put->Alpha = 0xff;
609 }
610 break;
611
612 default:
613 break;
614 }
615 }
616
617 ///////////////////////////////////////////////////////////////////////////////
ReadPixel24(image_reader * reader,int Index,Pixel * put)618 void png_reader::ReadPixel24(image_reader *reader, int Index, Pixel *put)
619 {
620 const GX_UBYTE *pGet = reader->mpGetData;
621
622 pGet += Index * 3;
623
624 put->Red = *pGet++;
625 put->Green = *pGet++;
626 put->Blue = *pGet++;
627
628 int num_trans;
629 png_color_16p trans_color;
630
631 if (png_get_tRNS(png_instance, png_info_ptr, NULL, &num_trans, &trans_color) == 0)
632 {
633 trans_color = NULL;
634 num_trans = 0;
635 }
636
637 if ((num_trans > 0) &&
638 (trans_color->red == put->Red) &&
639 (trans_color->green == put->Green) &&
640 (trans_color->blue == put->Blue))
641 {
642 //Transparent
643 put->Alpha = 0;
644 }
645 else
646 {
647 put->Alpha = 0xff;
648 }
649 }
650
651 ///////////////////////////////////////////////////////////////////////////////
ReadPixel64(image_reader * reader,int Index,Pixel * put)652 void png_reader::ReadPixel64(image_reader *reader, int Index, Pixel *put)
653 {
654 const GX_UBYTE *pGet = reader->mpGetData;
655
656 pGet += Index * 8;
657 put->Red = *pGet;
658 pGet += 2;
659 put->Green = *pGet;
660 pGet += 2;
661 put->Blue = *pGet;
662 pGet += 2;
663 put->Alpha = *pGet;
664 }
665
666 ///////////////////////////////////////////////////////////////////////////////
ReadPixel24Alpha(image_reader * reader,int Index,Pixel * put)667 void png_reader::ReadPixel24Alpha(image_reader *reader, int Index, Pixel *put)
668 {
669 const GX_UBYTE *pGet = reader->mpGetData;
670
671 pGet += Index * 4;
672 put->Red = *pGet++;
673 put->Green = *pGet++;
674 put->Blue = *pGet++;
675 put->Alpha = *pGet;
676 }
677
678
679 ///////////////////////////////////////////////////////////////////////////////
ReadPixel8Alpha(image_reader * reader,int Index,Pixel * put)680 void png_reader::ReadPixel8Alpha(image_reader *reader, int Index, Pixel *put)
681 {
682 const GX_UBYTE *pGet = reader->mpGetData;
683
684 pGet += Index * 2;
685 put->Red = put->Green = put->Blue = *pGet++;
686 put->Alpha = *pGet;
687 }
688
689 ///////////////////////////////////////////////////////////////////////////////
ReadPixel16To8(image_reader * reader,int Index,Pixel * put)690 void png_reader::ReadPixel16To8(image_reader *reader, int Index, Pixel *put)
691 {
692 const USHORT *pGet = (USHORT *)reader->mpGetData;
693 int gray;
694
695 pGet += Index;
696 gray = *pGet;
697
698 int num_trans;
699 png_color_16p trans_color;
700
701 if (png_get_tRNS(png_instance, png_info_ptr, NULL, &num_trans, &trans_color) == 0)
702 {
703 num_trans = 0;
704 trans_color = NULL;
705 }
706
707 if ((num_trans > 0) && (trans_color->gray == gray))
708 {
709 //Transparent
710 put->Alpha = 0;
711 }
712 else
713 {
714 put->Red = put->Green = put->Blue = (GX_UBYTE)gray;
715 put->Alpha = 0xff;
716 }
717 }
718
719 ///////////////////////////////////////////////////////////////////////////////
ReadPixel16Alpha(image_reader * reader,int Index,Pixel * put)720 void png_reader::ReadPixel16Alpha(image_reader *reader, int Index, Pixel *put)
721 {
722 const GX_UBYTE *pGet = reader->mpGetData;
723
724 pGet += (Index * 4);
725 put->Red = put->Green = put->Blue = *pGet;
726 pGet += 2;
727 put->Alpha = *pGet;
728 }
729
730 ///////////////////////////////////////////////////////////////////////////////
ReadDataFromIStream(png_structp png_ptr,png_bytep outBytes,png_size_t byteCountToRead)731 void png_reader::ReadDataFromIStream(png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead)
732 {
733 IStream *inputstream = (IStream *)png_get_io_ptr(png_ptr);
734
735 if (inputstream)
736 {
737 inputstream->Read(outBytes, byteCountToRead, GX_NULL);
738 }
739 }
740
741 ///////////////////////////////////////////////////////////////////////////////
ConfigureInternalFormat()742 void png_reader::ConfigureInternalFormat()
743 {
744 mInputHasAlpha = FALSE;
745
746 int bit_depth, color_type, num_trans;
747
748 //get information from the info
749 if (png_get_IHDR(m_png, m_info, NULL, NULL, &bit_depth, &color_type, NULL, NULL, NULL) == 0)
750 {
751 bit_depth = 0;
752 color_type = -1;
753 }
754
755 if (png_get_tRNS(m_png, m_info, NULL, &num_trans, NULL) == 0)
756 {
757 num_trans = 0;
758 }
759
760 switch(color_type)
761 {
762 case PNG_COLOR_TYPE_RGB:
763 if (num_trans > 0)
764 {
765 mInputHasAlpha = TRUE;
766 }
767
768 if (bit_depth == 8)
769 {
770 // use standard raw reader provided by base class
771 //SetDefaultPixelReader(24);
772 mpReadInputPixel = &png_reader::ReadPixel24;
773 }
774 else
775 {
776 // the input file has 16-bit channels. Use
777 // my own reader
778 mpReadInputPixel = &png_reader::ReadPixel48;
779 }
780 break;
781
782 case PNG_COLOR_TYPE_RGB_ALPHA:
783 mInputHasAlpha = TRUE;
784 if (bit_depth == 8)
785 {
786 mpReadInputPixel = &png_reader::ReadPixel24Alpha;
787 }
788 else
789 {
790 // the input file has 16-bit color channels
791 mpReadInputPixel = &png_reader::ReadPixel64;
792 }
793 break;
794
795 case PNG_COLOR_TYPE_PALETTE:
796 case PNG_COLOR_TYPE_GRAY:
797
798 if (num_trans > 0)
799 {
800 mInputHasAlpha = TRUE;
801 }
802
803 switch(bit_depth)
804 {
805 case 1:
806 mpReadInputPixel = &png_reader::ReadPixel1;
807 break;
808
809 case 2:
810 mpReadInputPixel = &png_reader::ReadPixel2;
811 break;
812
813 case 4:
814 mpReadInputPixel = &png_reader::ReadPixel4;
815 break;
816
817 case 8:
818 mpReadInputPixel = &png_reader::ReadPixel8;
819 break;
820
821 case 16:
822 mpReadInputPixel = &png_reader::ReadPixel16To8;
823 break;
824 }
825 break;
826
827 case PNG_COLOR_TYPE_GRAY_ALPHA:
828 mInputHasAlpha = TRUE;
829
830 if (bit_depth == 8)
831 {
832 mpReadInputPixel = &png_reader::ReadPixel8Alpha;
833 }
834 else
835 {
836 mpReadInputPixel = &png_reader::ReadPixel16Alpha;
837 }
838 break;
839 }
840 }
841