1 /*
2 ===========================================================================
3 png decoder
4 Copyright (C) 2007,2008 Joerg Dietrich
5 
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 ===========================================================================
20 */
21 
22 #include "tr_local.h"
23 
24 #include "../qcommon/puff.h"
25 
26 // we could limit the png size to a lower value here
27 #ifndef INT_MAX
28 #define INT_MAX 0x1fffffff
29 #endif
30 
31 /*
32 =================
33 PNG LOADING
34 =================
35 */
36 
37 /*
38  *  Quake 3 image format : RGBA
39  */
40 
41 #define Q3IMAGE_BYTESPERPIXEL (4)
42 
43 /*
44  *  PNG specifications
45  */
46 
47 /*
48  *  The first 8 Bytes of every PNG-File are a fixed signature
49  *  to identify the file as a PNG.
50  */
51 
52 #define PNG_Signature "\x89\x50\x4E\x47\xD\xA\x1A\xA"
53 #define PNG_Signature_Size (8)
54 
55 /*
56  *  After the signature diverse chunks follow.
57  *  A chunk consists of a header and if Length
58  *  is bigger than 0 a body and a CRC of the body follow.
59  */
60 
61 struct PNG_ChunkHeader
62 {
63 	uint32_t Length;
64 	uint32_t Type;
65 };
66 
67 #define PNG_ChunkHeader_Size (8)
68 
69 typedef uint32_t PNG_ChunkCRC;
70 
71 #define PNG_ChunkCRC_Size (4)
72 
73 /*
74  *  We use the following ChunkTypes.
75  *  All others are ignored.
76  */
77 
78 #define MAKE_CHUNKTYPE(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | ((d)))
79 
80 #define PNG_ChunkType_IHDR MAKE_CHUNKTYPE('I', 'H', 'D', 'R')
81 #define PNG_ChunkType_PLTE MAKE_CHUNKTYPE('P', 'L', 'T', 'E')
82 #define PNG_ChunkType_IDAT MAKE_CHUNKTYPE('I', 'D', 'A', 'T')
83 #define PNG_ChunkType_IEND MAKE_CHUNKTYPE('I', 'E', 'N', 'D')
84 #define PNG_ChunkType_tRNS MAKE_CHUNKTYPE('t', 'R', 'N', 'S')
85 
86 /*
87  *  Per specification the first chunk after the signature SHALL be IHDR.
88  */
89 
90 struct PNG_Chunk_IHDR
91 {
92 	uint32_t Width;
93 	uint32_t Height;
94 	uint8_t  BitDepth;
95 	uint8_t  ColourType;
96 	uint8_t  CompressionMethod;
97 	uint8_t  FilterMethod;
98 	uint8_t  InterlaceMethod;
99 };
100 
101 #define PNG_Chunk_IHDR_Size (13)
102 
103 /*
104  *  ColourTypes
105  */
106 
107 #define PNG_ColourType_Grey      (0)
108 #define PNG_ColourType_True      (2)
109 #define PNG_ColourType_Indexed   (3)
110 #define PNG_ColourType_GreyAlpha (4)
111 #define PNG_ColourType_TrueAlpha (6)
112 
113 /*
114  *  number of colour components
115  *
116  *  Grey      : 1 grey
117  *  True      : 1 R, 1 G, 1 B
118  *  Indexed   : 1 index
119  *  GreyAlpha : 1 grey, 1 alpha
120  *  TrueAlpha : 1 R, 1 G, 1 B, 1 alpha
121  */
122 
123 #define PNG_NumColourComponents_Grey      (1)
124 #define PNG_NumColourComponents_True      (3)
125 #define PNG_NumColourComponents_Indexed   (1)
126 #define PNG_NumColourComponents_GreyAlpha (2)
127 #define PNG_NumColourComponents_TrueAlpha (4)
128 
129 /*
130  *  For the different ColourTypes
131  *  different BitDepths are specified.
132  */
133 
134 #define PNG_BitDepth_1  ( 1)
135 #define PNG_BitDepth_2  ( 2)
136 #define PNG_BitDepth_4  ( 4)
137 #define PNG_BitDepth_8  ( 8)
138 #define PNG_BitDepth_16 (16)
139 
140 /*
141  *  Only one valid CompressionMethod is standardized.
142  */
143 
144 #define PNG_CompressionMethod_0 (0)
145 
146 /*
147  *  Only one valid FilterMethod is currently standardized.
148  */
149 
150 #define PNG_FilterMethod_0 (0)
151 
152 /*
153  *  This FilterMethod defines 5 FilterTypes
154  */
155 
156 #define PNG_FilterType_None    (0)
157 #define PNG_FilterType_Sub     (1)
158 #define PNG_FilterType_Up      (2)
159 #define PNG_FilterType_Average (3)
160 #define PNG_FilterType_Paeth   (4)
161 
162 /*
163  *  Two InterlaceMethods are standardized :
164  *  0 - NonInterlaced
165  *  1 - Interlaced
166  */
167 
168 #define PNG_InterlaceMethod_NonInterlaced (0)
169 #define PNG_InterlaceMethod_Interlaced    (1)
170 
171 /*
172  *  The Adam7 interlace method uses 7 passes.
173  */
174 
175 #define PNG_Adam7_NumPasses (7)
176 
177 /*
178  *  The compressed data starts with a header ...
179  */
180 
181 struct PNG_ZlibHeader
182 {
183 	uint8_t CompressionMethod;
184 	uint8_t Flags;
185 };
186 
187 #define PNG_ZlibHeader_Size (2)
188 
189 /*
190  *  ... and is followed by a check value
191  */
192 
193 #define PNG_ZlibCheckValue_Size (4)
194 
195 /*
196  *  Some support functions for buffered files follow.
197  */
198 
199 /*
200  *  buffered file representation
201  */
202 
203 struct BufferedFile
204 {
205 	byte *Buffer;
206 	int   Length;
207 	byte *Ptr;
208 	int   BytesLeft;
209 };
210 
211 /*
212  *  Read a file into a buffer.
213  */
214 
ReadBufferedFile(const char * name)215 static struct BufferedFile *ReadBufferedFile(const char *name)
216 {
217 	struct BufferedFile *BF;
218 
219 	/*
220 	 *  input verification
221 	 */
222 
223 	if(!name)
224 	{
225 		return(NULL);
226 	}
227 
228 	/*
229 	 *  Allocate control struct.
230 	 */
231 
232 	BF = ri.Malloc(sizeof(struct BufferedFile));
233 	if(!BF)
234 	{
235 		return(NULL);
236 	}
237 
238 	/*
239 	 *  Initialize the structs components.
240 	 */
241 
242 	BF->Length    = 0;
243 	BF->Buffer    = NULL;
244 	BF->Ptr       = NULL;
245 	BF->BytesLeft = 0;
246 
247 	/*
248 	 *  Read the file.
249 	 */
250 
251 	BF->Length = ri.FS_ReadFile((char *) name, (void **) &BF->Buffer);
252 
253 	/*
254 	 *  Did we get it? Is it big enough?
255 	 */
256 
257 	if(!(BF->Buffer && (BF->Length > 0)))
258 	{
259 		ri.Free(BF);
260 
261 		return(NULL);
262 	}
263 
264 	/*
265 	 *  Set the pointers and counters.
266 	 */
267 
268 	BF->Ptr       = BF->Buffer;
269 	BF->BytesLeft = BF->Length;
270 
271 	return(BF);
272 }
273 
274 /*
275  *  Close a buffered file.
276  */
277 
CloseBufferedFile(struct BufferedFile * BF)278 static void CloseBufferedFile(struct BufferedFile *BF)
279 {
280 	if(BF)
281 	{
282 		if(BF->Buffer)
283 		{
284 			ri.FS_FreeFile(BF->Buffer);
285 		}
286 
287 		ri.Free(BF);
288 	}
289 }
290 
291 /*
292  *  Get a pointer to the requested bytes.
293  */
294 
BufferedFileRead(struct BufferedFile * BF,unsigned Length)295 static void *BufferedFileRead(struct BufferedFile *BF, unsigned Length)
296 {
297 	void *RetVal;
298 
299 	/*
300 	 *  input verification
301 	 */
302 
303 	if(!(BF && Length))
304 	{
305 		return(NULL);
306 	}
307 
308 	/*
309 	 *  not enough bytes left
310 	 */
311 
312 	if(Length > BF->BytesLeft)
313 	{
314 		return(NULL);
315 	}
316 
317 	/*
318 	 *  the pointer to the requested data
319 	 */
320 
321 	RetVal = BF->Ptr;
322 
323 	/*
324 	 *  Raise the pointer and counter.
325 	 */
326 
327 	BF->Ptr       += Length;
328 	BF->BytesLeft -= Length;
329 
330 	return(RetVal);
331 }
332 
333 /*
334  *  Rewind the buffer.
335  */
336 
BufferedFileRewind(struct BufferedFile * BF,unsigned Offset)337 static qboolean BufferedFileRewind(struct BufferedFile *BF, unsigned Offset)
338 {
339 	unsigned BytesRead;
340 
341 	/*
342 	 *  input verification
343 	 */
344 
345 	if(!BF)
346 	{
347 		return(qfalse);
348 	}
349 
350 	/*
351 	 *  special trick to rewind to the beginning of the buffer
352 	 */
353 
354 	if(Offset == (unsigned)-1)
355 	{
356 		BF->Ptr       = BF->Buffer;
357 		BF->BytesLeft = BF->Length;
358 
359 		return(qtrue);
360 	}
361 
362 	/*
363 	 *  How many bytes do we have already read?
364 	 */
365 
366 	BytesRead = BF->Ptr - BF->Buffer;
367 
368 	/*
369 	 *  We can only rewind to the beginning of the BufferedFile.
370 	 */
371 
372 	if(Offset > BytesRead)
373 	{
374 		return(qfalse);
375 	}
376 
377 	/*
378 	 *  lower the pointer and counter.
379 	 */
380 
381 	BF->Ptr       -= Offset;
382 	BF->BytesLeft += Offset;
383 
384 	return(qtrue);
385 }
386 
387 /*
388  *  Skip some bytes.
389  */
390 
BufferedFileSkip(struct BufferedFile * BF,unsigned Offset)391 static qboolean BufferedFileSkip(struct BufferedFile *BF, unsigned Offset)
392 {
393 	/*
394 	 *  input verification
395 	 */
396 
397 	if(!BF)
398 	{
399 		return(qfalse);
400 	}
401 
402 	/*
403 	 *  We can only skip to the end of the BufferedFile.
404 	 */
405 
406 	if(Offset > BF->BytesLeft)
407 	{
408 		return(qfalse);
409 	}
410 
411 	/*
412 	 *  lower the pointer and counter.
413 	 */
414 
415 	BF->Ptr       += Offset;
416 	BF->BytesLeft -= Offset;
417 
418 	return(qtrue);
419 }
420 
421 /*
422  *  Find a chunk
423  */
424 
FindChunk(struct BufferedFile * BF,uint32_t ChunkType)425 static qboolean FindChunk(struct BufferedFile *BF, uint32_t ChunkType)
426 {
427 	struct PNG_ChunkHeader *CH;
428 
429 	uint32_t Length;
430 	uint32_t Type;
431 
432 	/*
433 	 *  input verification
434 	 */
435 
436 	if(!BF)
437 	{
438 		return(qfalse);
439 	}
440 
441 	/*
442 	 *  cycle trough the chunks
443 	 */
444 
445 	while(qtrue)
446 	{
447 		/*
448 		 *  Read the chunk-header.
449 		 */
450 
451 		CH = BufferedFileRead(BF, PNG_ChunkHeader_Size);
452 		if(!CH)
453 		{
454 			return(qfalse);
455 		}
456 
457 		/*
458 		 *  Do not swap the original types
459 		 *  they might be needed later.
460 		 */
461 
462 		Length = BigLong(CH->Length);
463 		Type   = BigLong(CH->Type);
464 
465 		/*
466 		 *  We found it!
467 		 */
468 
469 		if(Type == ChunkType)
470 		{
471 			/*
472 			 *  Rewind to the start of the chunk.
473 			 */
474 
475 			BufferedFileRewind(BF, PNG_ChunkHeader_Size);
476 
477 			break;
478 		}
479 		else
480 		{
481 			/*
482 			 *  Skip the rest of the chunk.
483 			 */
484 
485 			if(Length)
486 			{
487 				if(!BufferedFileSkip(BF, Length + PNG_ChunkCRC_Size))
488 				{
489 					return(qfalse);
490 				}
491 			}
492 		}
493 	}
494 
495 	return(qtrue);
496 }
497 
498 /*
499  *  Decompress all IDATs
500  */
501 
DecompressIDATs(struct BufferedFile * BF,uint8_t ** Buffer)502 static uint32_t DecompressIDATs(struct BufferedFile *BF, uint8_t **Buffer)
503 {
504 	uint8_t  *DecompressedData;
505 	uint32_t  DecompressedDataLength;
506 
507 	uint8_t  *CompressedData;
508 	uint8_t  *CompressedDataPtr;
509 	uint32_t  CompressedDataLength;
510 
511 	struct PNG_ChunkHeader *CH;
512 
513 	uint32_t Length;
514 	uint32_t Type;
515 
516 	int BytesToRewind;
517 
518 	int32_t   puffResult;
519 	uint8_t  *puffDest;
520 	uint32_t  puffDestLen;
521 	uint8_t  *puffSrc;
522 	uint32_t  puffSrcLen;
523 
524 	/*
525 	 *  input verification
526 	 */
527 
528 	if(!(BF && Buffer))
529 	{
530 		return(-1);
531 	}
532 
533 	/*
534 	 *  some zeroing
535 	 */
536 
537 	DecompressedData = NULL;
538 	DecompressedDataLength = 0;
539 	*Buffer = DecompressedData;
540 
541 	CompressedData = NULL;
542 	CompressedDataLength = 0;
543 
544 	BytesToRewind = 0;
545 
546 	/*
547 	 *  Find the first IDAT chunk.
548 	 */
549 
550 	if(!FindChunk(BF, PNG_ChunkType_IDAT))
551 	{
552 		return(-1);
553 	}
554 
555 	/*
556 	 *  Count the size of the uncompressed data
557 	 */
558 
559 	while(qtrue)
560 	{
561 		/*
562 		 *  Read chunk header
563 		 */
564 
565 		CH = BufferedFileRead(BF, PNG_ChunkHeader_Size);
566 		if(!CH)
567 		{
568 			/*
569 			 *  Rewind to the start of this adventure
570 			 *  and return unsuccessfull
571 			 */
572 
573 			BufferedFileRewind(BF, BytesToRewind);
574 
575 			return(-1);
576 		}
577 
578 		/*
579 		 *  Length and Type of chunk
580 		 */
581 
582 		Length = BigLong(CH->Length);
583 		Type   = BigLong(CH->Type);
584 
585 		/*
586 		 *  We have reached the end of the IDAT chunks
587 		 */
588 
589 		if(!(Type == PNG_ChunkType_IDAT))
590 		{
591 			BufferedFileRewind(BF, PNG_ChunkHeader_Size);
592 
593 			break;
594 		}
595 
596 		/*
597 		 *  Add chunk header to count.
598 		 */
599 
600 		BytesToRewind += PNG_ChunkHeader_Size;
601 
602 		/*
603 		 *  Skip to next chunk
604 		 */
605 
606 		if(Length)
607 		{
608 			if(!BufferedFileSkip(BF, Length + PNG_ChunkCRC_Size))
609 			{
610 				BufferedFileRewind(BF, BytesToRewind);
611 
612 				return(-1);
613 			}
614 
615 			BytesToRewind += Length + PNG_ChunkCRC_Size;
616 			CompressedDataLength += Length;
617 		}
618 	}
619 
620 	BufferedFileRewind(BF, BytesToRewind);
621 
622 	CompressedData = ri.Malloc(CompressedDataLength);
623 	if(!CompressedData)
624 	{
625 		return(-1);
626 	}
627 
628 	CompressedDataPtr = CompressedData;
629 
630 	/*
631 	 *  Collect the compressed Data
632 	 */
633 
634 	while(qtrue)
635 	{
636 		/*
637 		 *  Read chunk header
638 		 */
639 
640 		CH = BufferedFileRead(BF, PNG_ChunkHeader_Size);
641 		if(!CH)
642 		{
643 			ri.Free(CompressedData);
644 
645 			return(-1);
646 		}
647 
648 		/*
649 		 *  Length and Type of chunk
650 		 */
651 
652 		Length = BigLong(CH->Length);
653 		Type   = BigLong(CH->Type);
654 
655 		/*
656 		 *  We have reached the end of the IDAT chunks
657 		 */
658 
659 		if(!(Type == PNG_ChunkType_IDAT))
660 		{
661 			BufferedFileRewind(BF, PNG_ChunkHeader_Size);
662 
663 			break;
664 		}
665 
666 		/*
667 		 *  Copy the Data
668 		 */
669 
670 		if(Length)
671 		{
672 			uint8_t *OrigCompressedData;
673 
674 			OrigCompressedData = BufferedFileRead(BF, Length);
675 			if(!OrigCompressedData)
676 			{
677 				ri.Free(CompressedData);
678 
679 				return(-1);
680 			}
681 
682 			if(!BufferedFileSkip(BF, PNG_ChunkCRC_Size))
683 			{
684 				ri.Free(CompressedData);
685 
686 				return(-1);
687 			}
688 
689 			memcpy(CompressedDataPtr, OrigCompressedData, Length);
690 			CompressedDataPtr += Length;
691 		}
692 	}
693 
694 	/*
695 	 *  Let puff() calculate the decompressed data length.
696 	 */
697 
698 	puffDest    = NULL;
699 	puffDestLen = 0;
700 
701 	/*
702 	 *  The zlib header and checkvalue don't belong to the compressed data.
703 	 */
704 
705 	puffSrc    = CompressedData + PNG_ZlibHeader_Size;
706 	puffSrcLen = CompressedDataLength - PNG_ZlibHeader_Size - PNG_ZlibCheckValue_Size;
707 
708 	/*
709 	 *  first puff() to calculate the size of the uncompressed data
710 	 */
711 
712 	puffResult = puff(puffDest, &puffDestLen, puffSrc, &puffSrcLen);
713 	if(!((puffResult == 0) && (puffDestLen > 0)))
714 	{
715 		ri.Free(CompressedData);
716 
717 		return(-1);
718 	}
719 
720 	/*
721 	 *  Allocate the buffer for the uncompressed data.
722 	 */
723 
724 	DecompressedData = ri.Malloc(puffDestLen);
725 	if(!DecompressedData)
726 	{
727 		ri.Free(CompressedData);
728 
729 		return(-1);
730 	}
731 
732 	/*
733 	 *  Set the input again in case something was changed by the last puff() .
734 	 */
735 
736 	puffDest   = DecompressedData;
737 	puffSrc    = CompressedData + PNG_ZlibHeader_Size;
738 	puffSrcLen = CompressedDataLength - PNG_ZlibHeader_Size - PNG_ZlibCheckValue_Size;
739 
740 	/*
741 	 *  decompression puff()
742 	 */
743 
744 	puffResult = puff(puffDest, &puffDestLen, puffSrc, &puffSrcLen);
745 
746 	/*
747 	 *  The compressed data is not needed anymore.
748 	 */
749 
750 	ri.Free(CompressedData);
751 
752 	/*
753 	 *  Check if the last puff() was successfull.
754 	 */
755 
756 	if(!((puffResult == 0) && (puffDestLen > 0)))
757 	{
758 		ri.Free(DecompressedData);
759 
760 		return(-1);
761 	}
762 
763 	/*
764 	 *  Set the output of this function.
765 	 */
766 
767 	DecompressedDataLength = puffDestLen;
768 	*Buffer = DecompressedData;
769 
770 	return(DecompressedDataLength);
771 }
772 
773 /*
774  *  the Paeth predictor
775  */
776 
PredictPaeth(uint8_t a,uint8_t b,uint8_t c)777 static uint8_t PredictPaeth(uint8_t a, uint8_t b, uint8_t c)
778 {
779 	/*
780 	 *  a == Left
781 	 *  b == Up
782 	 *  c == UpLeft
783 	 */
784 
785 	uint8_t Pr;
786 	int p;
787 	int pa, pb, pc;
788 
789 	Pr = 0;
790 
791 	p  = ((int) a) + ((int) b) - ((int) c);
792 	pa = abs(p - ((int) a));
793 	pb = abs(p - ((int) b));
794 	pc = abs(p - ((int) c));
795 
796 	if((pa <= pb) && (pa <= pc))
797 	{
798 		Pr = a;
799 	}
800 	else if(pb <= pc)
801 	{
802 		Pr = b;
803 	}
804 	else
805 	{
806 		Pr = c;
807 	}
808 
809 	return(Pr);
810 
811 }
812 
813 /*
814  *  Reverse the filters.
815  */
816 
UnfilterImage(uint8_t * DecompressedData,uint32_t ImageHeight,uint32_t BytesPerScanline,uint32_t BytesPerPixel)817 static qboolean UnfilterImage(uint8_t  *DecompressedData,
818 		uint32_t  ImageHeight,
819 		uint32_t  BytesPerScanline,
820 		uint32_t  BytesPerPixel)
821 {
822 	uint8_t   *DecompPtr;
823 	uint8_t   FilterType;
824 	uint8_t  *PixelLeft, *PixelUp, *PixelUpLeft;
825 	uint32_t  w, h, p;
826 
827 	/*
828 	 *  some zeros for the filters
829 	 */
830 
831 	uint8_t Zeros[8] = {0, 0, 0, 0, 0, 0, 0, 0};
832 
833 	/*
834 	 *  input verification
835 	 */
836 
837 	if(!(DecompressedData && BytesPerPixel))
838 	{
839 		return(qfalse);
840 	}
841 
842 	/*
843 	 *  ImageHeight and BytesPerScanline can be zero in small interlaced images.
844 	 */
845 
846 	if((!ImageHeight) || (!BytesPerScanline))
847 	{
848 		return(qtrue);
849 	}
850 
851 	/*
852 	 *  Set the pointer to the start of the decompressed Data.
853 	 */
854 
855 	DecompPtr = DecompressedData;
856 
857 	/*
858 	 *  Un-filtering is done in place.
859 	 */
860 
861 	/*
862 	 *  Go trough all scanlines.
863 	 */
864 
865 	for(h = 0; h < ImageHeight; h++)
866 	{
867 		/*
868 		 *  Every scanline starts with a FilterType byte.
869 		 */
870 
871 		FilterType = *DecompPtr;
872 		DecompPtr++;
873 
874 		/*
875 		 *  Left pixel of the first byte in a scanline is zero.
876 		 */
877 
878 		PixelLeft = Zeros;
879 
880 		/*
881 		 *  Set PixelUp to previous line only if we are on the second line or above.
882 		 *
883 		 *  Plus one byte for the FilterType
884 		 */
885 
886 		if(h > 0)
887 		{
888 			PixelUp = DecompPtr - (BytesPerScanline + 1);
889 		}
890 		else
891 		{
892 			PixelUp = Zeros;
893 		}
894 
895 		/*
896 		 * The pixel left to the first pixel of the previous scanline is zero too.
897 		 */
898 
899 		PixelUpLeft = Zeros;
900 
901 		/*
902 		 *  Cycle trough all pixels of the scanline.
903 		 */
904 
905 		for(w = 0; w < (BytesPerScanline / BytesPerPixel); w++)
906 		{
907 			/*
908 			 *  Cycle trough the bytes of the pixel.
909 			 */
910 
911 			for(p = 0; p < BytesPerPixel; p++)
912 			{
913 				switch(FilterType)
914 				{
915 					case PNG_FilterType_None :
916 					{
917 						/*
918 						 *  The byte is unfiltered.
919 						 */
920 
921 						break;
922 					}
923 
924 					case PNG_FilterType_Sub :
925 					{
926 						DecompPtr[p] += PixelLeft[p];
927 
928 						break;
929 					}
930 
931 					case PNG_FilterType_Up :
932 					{
933 						DecompPtr[p] += PixelUp[p];
934 
935 						break;
936 					}
937 
938 					case PNG_FilterType_Average :
939 					{
940 						DecompPtr[p] += ((uint8_t) ((((uint16_t) PixelLeft[p]) + ((uint16_t) PixelUp[p])) / 2));
941 
942 						break;
943 					}
944 
945 					case PNG_FilterType_Paeth :
946 					{
947 						DecompPtr[p] += PredictPaeth(PixelLeft[p], PixelUp[p], PixelUpLeft[p]);
948 
949 						break;
950 					}
951 
952 					default :
953 					{
954 						return(qfalse);
955 					}
956 				}
957 			}
958 
959 			PixelLeft = DecompPtr;
960 
961 			/*
962 			 *  We only have a upleft pixel if we are on the second line or above.
963 			 */
964 
965 			if(h > 0)
966 			{
967 				PixelUpLeft = DecompPtr - (BytesPerScanline + 1);
968 			}
969 
970 			/*
971 			 *  Skip to the next pixel.
972 			 */
973 
974 			DecompPtr += BytesPerPixel;
975 
976 			/*
977 			 *  We only have a previous line if we are on the second line and above.
978 			 */
979 
980 			if(h > 0)
981 			{
982 				PixelUp = DecompPtr - (BytesPerScanline + 1);
983 			}
984 		}
985 	}
986 
987 	return(qtrue);
988 }
989 
990 /*
991  *  Convert a raw input pixel to Quake 3 RGA format.
992  */
993 
ConvertPixel(struct PNG_Chunk_IHDR * IHDR,byte * OutPtr,uint8_t * DecompPtr,qboolean HasTransparentColour,uint8_t * TransparentColour,uint8_t * OutPal)994 static qboolean ConvertPixel(struct PNG_Chunk_IHDR *IHDR,
995 		byte                  *OutPtr,
996 		uint8_t               *DecompPtr,
997 		qboolean               HasTransparentColour,
998 		uint8_t               *TransparentColour,
999 		uint8_t               *OutPal)
1000 {
1001 	/*
1002 	 *  input verification
1003 	 */
1004 
1005 	if(!(IHDR && OutPtr && DecompPtr && TransparentColour && OutPal))
1006 	{
1007 		return(qfalse);
1008 	}
1009 
1010 	switch(IHDR->ColourType)
1011 	{
1012 		case PNG_ColourType_Grey :
1013 		{
1014 			switch(IHDR->BitDepth)
1015 			{
1016 				case PNG_BitDepth_1 :
1017 				case PNG_BitDepth_2 :
1018 				case PNG_BitDepth_4 :
1019 				{
1020 					uint8_t Step;
1021 					uint8_t GreyValue;
1022 
1023 					Step = 0xFF / ((1 << IHDR->BitDepth) - 1);
1024 
1025 					GreyValue = DecompPtr[0] * Step;
1026 
1027 					OutPtr[0] = GreyValue;
1028 					OutPtr[1] = GreyValue;
1029 					OutPtr[2] = GreyValue;
1030 					OutPtr[3] = 0xFF;
1031 
1032 					/*
1033 					 *  Grey supports full transparency for one specified colour
1034 					 */
1035 
1036 					if(HasTransparentColour)
1037 					{
1038 						if(TransparentColour[1] == DecompPtr[0])
1039 						{
1040 							OutPtr[3] = 0x00;
1041 						}
1042 					}
1043 
1044 
1045 					break;
1046 				}
1047 
1048 				case PNG_BitDepth_8 :
1049 				case PNG_BitDepth_16 :
1050 				{
1051 					OutPtr[0] = DecompPtr[0];
1052 					OutPtr[1] = DecompPtr[0];
1053 					OutPtr[2] = DecompPtr[0];
1054 					OutPtr[3] = 0xFF;
1055 
1056 					/*
1057 					 *  Grey supports full transparency for one specified colour
1058 					 */
1059 
1060 					if(HasTransparentColour)
1061 					{
1062 						if(IHDR->BitDepth == PNG_BitDepth_8)
1063 						{
1064 							if(TransparentColour[1] == DecompPtr[0])
1065 							{
1066 								OutPtr[3] = 0x00;
1067 							}
1068 						}
1069 						else
1070 						{
1071 							if((TransparentColour[0] == DecompPtr[0]) && (TransparentColour[1] == DecompPtr[1]))
1072 							{
1073 								OutPtr[3] = 0x00;
1074 							}
1075 						}
1076 					}
1077 
1078 					break;
1079 				}
1080 
1081 				default :
1082 				{
1083 					return(qfalse);
1084 				}
1085 			}
1086 
1087 			break;
1088 		}
1089 
1090 		case PNG_ColourType_True :
1091 		{
1092 			switch(IHDR->BitDepth)
1093 			{
1094 				case PNG_BitDepth_8 :
1095 				{
1096 					OutPtr[0] = DecompPtr[0];
1097 					OutPtr[1] = DecompPtr[1];
1098 					OutPtr[2] = DecompPtr[2];
1099 					OutPtr[3] = 0xFF;
1100 
1101 					/*
1102 					 *  True supports full transparency for one specified colour
1103 					 */
1104 
1105 					if(HasTransparentColour)
1106 					{
1107 						if((TransparentColour[1] == DecompPtr[0]) &&
1108 								(TransparentColour[3] == DecompPtr[1]) &&
1109 								(TransparentColour[5] == DecompPtr[2]))
1110 						{
1111 							OutPtr[3] = 0x00;
1112 						}
1113 					}
1114 
1115 					break;
1116 				}
1117 
1118 				case PNG_BitDepth_16 :
1119 				{
1120 					/*
1121 					 *  We use only the upper byte.
1122 					 */
1123 
1124 					OutPtr[0] = DecompPtr[0];
1125 					OutPtr[1] = DecompPtr[2];
1126 					OutPtr[2] = DecompPtr[4];
1127 					OutPtr[3] = 0xFF;
1128 
1129 					/*
1130 					 *  True supports full transparency for one specified colour
1131 					 */
1132 
1133 					if(HasTransparentColour)
1134 					{
1135 						if((TransparentColour[0] == DecompPtr[0]) && (TransparentColour[1] == DecompPtr[1]) &&
1136 								(TransparentColour[2] == DecompPtr[2]) && (TransparentColour[3] == DecompPtr[3]) &&
1137 								(TransparentColour[4] == DecompPtr[4]) && (TransparentColour[5] == DecompPtr[5]))
1138 						{
1139 							OutPtr[3] = 0x00;
1140 						}
1141 					}
1142 
1143 					break;
1144 				}
1145 
1146 				default :
1147 				{
1148 					return(qfalse);
1149 				}
1150 			}
1151 
1152 			break;
1153 		}
1154 
1155 		case PNG_ColourType_Indexed :
1156 		{
1157 			OutPtr[0] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 0];
1158 			OutPtr[1] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 1];
1159 			OutPtr[2] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 2];
1160 			OutPtr[3] = OutPal[DecompPtr[0] * Q3IMAGE_BYTESPERPIXEL + 3];
1161 
1162 			break;
1163 		}
1164 
1165 		case PNG_ColourType_GreyAlpha :
1166 		{
1167 			switch(IHDR->BitDepth)
1168 			{
1169 				case PNG_BitDepth_8 :
1170 				{
1171 					OutPtr[0] = DecompPtr[0];
1172 					OutPtr[1] = DecompPtr[0];
1173 					OutPtr[2] = DecompPtr[0];
1174 					OutPtr[3] = DecompPtr[1];
1175 
1176 					break;
1177 				}
1178 
1179 				case PNG_BitDepth_16 :
1180 				{
1181 					/*
1182 					 *  We use only the upper byte.
1183 					 */
1184 
1185 					OutPtr[0] = DecompPtr[0];
1186 					OutPtr[1] = DecompPtr[0];
1187 					OutPtr[2] = DecompPtr[0];
1188 					OutPtr[3] = DecompPtr[2];
1189 
1190 					break;
1191 				}
1192 
1193 				default :
1194 				{
1195 					return(qfalse);
1196 				}
1197 			}
1198 
1199 			break;
1200 		}
1201 
1202 		case PNG_ColourType_TrueAlpha :
1203 		{
1204 			switch(IHDR->BitDepth)
1205 			{
1206 				case PNG_BitDepth_8 :
1207 				{
1208 					OutPtr[0] = DecompPtr[0];
1209 					OutPtr[1] = DecompPtr[1];
1210 					OutPtr[2] = DecompPtr[2];
1211 					OutPtr[3] = DecompPtr[3];
1212 
1213 					break;
1214 				}
1215 
1216 				case PNG_BitDepth_16 :
1217 				{
1218 					/*
1219 					 *  We use only the upper byte.
1220 					 */
1221 
1222 					OutPtr[0] = DecompPtr[0];
1223 					OutPtr[1] = DecompPtr[2];
1224 					OutPtr[2] = DecompPtr[4];
1225 					OutPtr[3] = DecompPtr[6];
1226 
1227 					break;
1228 				}
1229 
1230 				default :
1231 				{
1232 					return(qfalse);
1233 				}
1234 			}
1235 
1236 			break;
1237 		}
1238 
1239 		default :
1240 		{
1241 			return(qfalse);
1242 		}
1243 	}
1244 
1245 	return(qtrue);
1246 }
1247 
1248 
1249 /*
1250  *  Decode a non-interlaced image.
1251  */
1252 
DecodeImageNonInterlaced(struct PNG_Chunk_IHDR * IHDR,byte * OutBuffer,uint8_t * DecompressedData,uint32_t DecompressedDataLength,qboolean HasTransparentColour,uint8_t * TransparentColour,uint8_t * OutPal)1253 static qboolean DecodeImageNonInterlaced(struct PNG_Chunk_IHDR *IHDR,
1254 		byte                  *OutBuffer,
1255 		uint8_t               *DecompressedData,
1256 		uint32_t               DecompressedDataLength,
1257 		qboolean               HasTransparentColour,
1258 		uint8_t               *TransparentColour,
1259 		uint8_t               *OutPal)
1260 {
1261 	uint32_t IHDR_Width;
1262 	uint32_t IHDR_Height;
1263 	uint32_t BytesPerScanline, BytesPerPixel, PixelsPerByte;
1264 	uint32_t  w, h, p;
1265 	byte *OutPtr;
1266 	uint8_t *DecompPtr;
1267 
1268 	/*
1269 	 *  input verification
1270 	 */
1271 
1272 	if(!(IHDR && OutBuffer && DecompressedData && DecompressedDataLength && TransparentColour && OutPal))
1273 	{
1274 		return(qfalse);
1275 	}
1276 
1277 	/*
1278 	 *  byte swapping
1279 	 */
1280 
1281 	IHDR_Width  = BigLong(IHDR->Width);
1282 	IHDR_Height = BigLong(IHDR->Height);
1283 
1284 	/*
1285 	 *  information for un-filtering
1286 	 */
1287 
1288 	switch(IHDR->ColourType)
1289 	{
1290 		case PNG_ColourType_Grey :
1291 		{
1292 			switch(IHDR->BitDepth)
1293 			{
1294 				case PNG_BitDepth_1 :
1295 				case PNG_BitDepth_2 :
1296 				case PNG_BitDepth_4 :
1297 				{
1298 					BytesPerPixel    = 1;
1299 					PixelsPerByte    = 8 / IHDR->BitDepth;
1300 
1301 					break;
1302 				}
1303 
1304 				case PNG_BitDepth_8  :
1305 				case PNG_BitDepth_16 :
1306 				{
1307 					BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_Grey;
1308 					PixelsPerByte    = 1;
1309 
1310 					break;
1311 				}
1312 
1313 				default :
1314 				{
1315 					return(qfalse);
1316 				}
1317 			}
1318 
1319 			break;
1320 		}
1321 
1322 		case PNG_ColourType_True :
1323 		{
1324 			switch(IHDR->BitDepth)
1325 			{
1326 				case PNG_BitDepth_8  :
1327 				case PNG_BitDepth_16 :
1328 				{
1329 					BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_True;
1330 					PixelsPerByte    = 1;
1331 
1332 					break;
1333 				}
1334 
1335 				default :
1336 				{
1337 					return(qfalse);
1338 				}
1339 			}
1340 
1341 			break;
1342 		}
1343 
1344 		case PNG_ColourType_Indexed :
1345 		{
1346 			switch(IHDR->BitDepth)
1347 			{
1348 				case PNG_BitDepth_1 :
1349 				case PNG_BitDepth_2 :
1350 				case PNG_BitDepth_4 :
1351 				{
1352 					BytesPerPixel    = 1;
1353 					PixelsPerByte    = 8 / IHDR->BitDepth;
1354 
1355 					break;
1356 				}
1357 
1358 				case PNG_BitDepth_8 :
1359 				{
1360 					BytesPerPixel    = PNG_NumColourComponents_Indexed;
1361 					PixelsPerByte    = 1;
1362 
1363 					break;
1364 				}
1365 
1366 				default :
1367 				{
1368 					return(qfalse);
1369 				}
1370 			}
1371 
1372 			break;
1373 		}
1374 
1375 		case PNG_ColourType_GreyAlpha :
1376 		{
1377 			switch(IHDR->BitDepth)
1378 			{
1379 				case PNG_BitDepth_8 :
1380 				case PNG_BitDepth_16 :
1381 				{
1382 					BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_GreyAlpha;
1383 					PixelsPerByte    = 1;
1384 
1385 					break;
1386 				}
1387 
1388 				default :
1389 				{
1390 					return(qfalse);
1391 				}
1392 			}
1393 
1394 			break;
1395 		}
1396 
1397 		case PNG_ColourType_TrueAlpha :
1398 		{
1399 			switch(IHDR->BitDepth)
1400 			{
1401 				case PNG_BitDepth_8 :
1402 				case PNG_BitDepth_16 :
1403 				{
1404 					BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_TrueAlpha;
1405 					PixelsPerByte    = 1;
1406 
1407 					break;
1408 				}
1409 
1410 				default :
1411 				{
1412 					return(qfalse);
1413 				}
1414 			}
1415 
1416 			break;
1417 		}
1418 
1419 		default :
1420 		{
1421 			return(qfalse);
1422 		}
1423 	}
1424 
1425 	/*
1426 	 *  Calculate the size of one scanline
1427 	 */
1428 
1429 	BytesPerScanline = (IHDR_Width * BytesPerPixel + (PixelsPerByte - 1)) / PixelsPerByte;
1430 
1431 	/*
1432 	 *  Check if we have enough data for the whole image.
1433 	 */
1434 
1435 	if(!(DecompressedDataLength == ((BytesPerScanline + 1) * IHDR_Height)))
1436 	{
1437 		return(qfalse);
1438 	}
1439 
1440 	/*
1441 	 *  Unfilter the image.
1442 	 */
1443 
1444 	if(!UnfilterImage(DecompressedData, IHDR_Height, BytesPerScanline, BytesPerPixel))
1445 	{
1446 		return(qfalse);
1447 	}
1448 
1449 	/*
1450 	 *  Set the working pointers to the beginning of the buffers.
1451 	 */
1452 
1453 	OutPtr = OutBuffer;
1454 	DecompPtr = DecompressedData;
1455 
1456 	/*
1457 	 *  Create the output image.
1458 	 */
1459 
1460 	for(h = 0; h < IHDR_Height; h++)
1461 	{
1462 		/*
1463 		 *  Count the pixels on the scanline for those multipixel bytes
1464 		 */
1465 
1466 		uint32_t CurrPixel;
1467 
1468 		/*
1469 		 *  skip FilterType
1470 		 */
1471 
1472 		DecompPtr++;
1473 
1474 		/*
1475 		 *  Reset the pixel count.
1476 		 */
1477 
1478 		CurrPixel = 0;
1479 
1480 		for(w = 0; w < (BytesPerScanline / BytesPerPixel); w++)
1481 		{
1482 			if(PixelsPerByte > 1)
1483 			{
1484 				uint8_t  Mask;
1485 				uint32_t Shift;
1486 				uint8_t  SinglePixel;
1487 
1488 				for(p = 0; p < PixelsPerByte; p++)
1489 				{
1490 					if(CurrPixel < IHDR_Width)
1491 					{
1492 						Mask  = (1 << IHDR->BitDepth) - 1;
1493 						Shift = (PixelsPerByte - 1 - p) * IHDR->BitDepth;
1494 
1495 						SinglePixel = ((DecompPtr[0] & (Mask << Shift)) >> Shift);
1496 
1497 						if(!ConvertPixel(IHDR, OutPtr, &SinglePixel, HasTransparentColour, TransparentColour, OutPal))
1498 						{
1499 							return(qfalse);
1500 						}
1501 
1502 						OutPtr += Q3IMAGE_BYTESPERPIXEL;
1503 						CurrPixel++;
1504 					}
1505 				}
1506 
1507 			}
1508 			else
1509 			{
1510 				if(!ConvertPixel(IHDR, OutPtr, DecompPtr, HasTransparentColour, TransparentColour, OutPal))
1511 				{
1512 					return(qfalse);
1513 				}
1514 
1515 
1516 				OutPtr += Q3IMAGE_BYTESPERPIXEL;
1517 			}
1518 
1519 			DecompPtr += BytesPerPixel;
1520 		}
1521 	}
1522 
1523 	return(qtrue);
1524 }
1525 
1526 /*
1527  *  Decode an interlaced image.
1528  */
1529 
DecodeImageInterlaced(struct PNG_Chunk_IHDR * IHDR,byte * OutBuffer,uint8_t * DecompressedData,uint32_t DecompressedDataLength,qboolean HasTransparentColour,uint8_t * TransparentColour,uint8_t * OutPal)1530 static qboolean DecodeImageInterlaced(struct PNG_Chunk_IHDR *IHDR,
1531 		byte                  *OutBuffer,
1532 		uint8_t               *DecompressedData,
1533 		uint32_t               DecompressedDataLength,
1534 		qboolean               HasTransparentColour,
1535 		uint8_t               *TransparentColour,
1536 		uint8_t               *OutPal)
1537 {
1538 	uint32_t IHDR_Width;
1539 	uint32_t IHDR_Height;
1540 	uint32_t BytesPerScanline[PNG_Adam7_NumPasses], BytesPerPixel, PixelsPerByte;
1541 	uint32_t PassWidth[PNG_Adam7_NumPasses], PassHeight[PNG_Adam7_NumPasses];
1542 	uint32_t WSkip[PNG_Adam7_NumPasses], WOffset[PNG_Adam7_NumPasses], HSkip[PNG_Adam7_NumPasses], HOffset[PNG_Adam7_NumPasses];
1543 	uint32_t w, h, p, a;
1544 	byte *OutPtr;
1545 	uint8_t *DecompPtr;
1546 	uint32_t TargetLength;
1547 
1548 	/*
1549 	 *  input verification
1550 	 */
1551 
1552 	if(!(IHDR && OutBuffer && DecompressedData && DecompressedDataLength && TransparentColour && OutPal))
1553 	{
1554 		return(qfalse);
1555 	}
1556 
1557 	/*
1558 	 *  byte swapping
1559 	 */
1560 
1561 	IHDR_Width  = BigLong(IHDR->Width);
1562 	IHDR_Height = BigLong(IHDR->Height);
1563 
1564 	/*
1565 	 *  Skip and Offset for the passes.
1566 	 */
1567 
1568 	WSkip[0]   = 8;
1569 	WOffset[0] = 0;
1570 	HSkip[0]   = 8;
1571 	HOffset[0] = 0;
1572 
1573 	WSkip[1]   = 8;
1574 	WOffset[1] = 4;
1575 	HSkip[1]   = 8;
1576 	HOffset[1] = 0;
1577 
1578 	WSkip[2]   = 4;
1579 	WOffset[2] = 0;
1580 	HSkip[2]   = 8;
1581 	HOffset[2] = 4;
1582 
1583 	WSkip[3]   = 4;
1584 	WOffset[3] = 2;
1585 	HSkip[3]   = 4;
1586 	HOffset[3] = 0;
1587 
1588 	WSkip[4]   = 2;
1589 	WOffset[4] = 0;
1590 	HSkip[4]   = 4;
1591 	HOffset[4] = 2;
1592 
1593 	WSkip[5]   = 2;
1594 	WOffset[5] = 1;
1595 	HSkip[5]   = 2;
1596 	HOffset[5] = 0;
1597 
1598 	WSkip[6]   = 1;
1599 	WOffset[6] = 0;
1600 	HSkip[6]   = 2;
1601 	HOffset[6] = 1;
1602 
1603 	/*
1604 	 *  Calculate the sizes of the passes.
1605 	 */
1606 
1607 	PassWidth[0]  = (IHDR_Width  + 7) / 8;
1608 	PassHeight[0] = (IHDR_Height + 7) / 8;
1609 
1610 	PassWidth[1]  = (IHDR_Width  + 3) / 8;
1611 	PassHeight[1] = (IHDR_Height + 7) / 8;
1612 
1613 	PassWidth[2]  = (IHDR_Width  + 3) / 4;
1614 	PassHeight[2] = (IHDR_Height + 3) / 8;
1615 
1616 	PassWidth[3]  = (IHDR_Width  + 1) / 4;
1617 	PassHeight[3] = (IHDR_Height + 3) / 4;
1618 
1619 	PassWidth[4]  = (IHDR_Width  + 1) / 2;
1620 	PassHeight[4] = (IHDR_Height + 1) / 4;
1621 
1622 	PassWidth[5]  = (IHDR_Width  + 0) / 2;
1623 	PassHeight[5] = (IHDR_Height + 1) / 2;
1624 
1625 	PassWidth[6]  = (IHDR_Width  + 0) / 1;
1626 	PassHeight[6] = (IHDR_Height + 0) / 2;
1627 
1628 	/*
1629 	 *  information for un-filtering
1630 	 */
1631 
1632 	switch(IHDR->ColourType)
1633 	{
1634 		case PNG_ColourType_Grey :
1635 		{
1636 			switch(IHDR->BitDepth)
1637 			{
1638 				case PNG_BitDepth_1 :
1639 				case PNG_BitDepth_2 :
1640 				case PNG_BitDepth_4 :
1641 				{
1642 					BytesPerPixel    = 1;
1643 					PixelsPerByte    = 8 / IHDR->BitDepth;
1644 
1645 					break;
1646 				}
1647 
1648 				case PNG_BitDepth_8  :
1649 				case PNG_BitDepth_16 :
1650 				{
1651 					BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_Grey;
1652 					PixelsPerByte    = 1;
1653 
1654 					break;
1655 				}
1656 
1657 				default :
1658 				{
1659 					return(qfalse);
1660 				}
1661 			}
1662 
1663 			break;
1664 		}
1665 
1666 		case PNG_ColourType_True :
1667 		{
1668 			switch(IHDR->BitDepth)
1669 			{
1670 				case PNG_BitDepth_8  :
1671 				case PNG_BitDepth_16 :
1672 				{
1673 					BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_True;
1674 					PixelsPerByte    = 1;
1675 
1676 					break;
1677 				}
1678 
1679 				default :
1680 				{
1681 					return(qfalse);
1682 				}
1683 			}
1684 
1685 			break;
1686 		}
1687 
1688 		case PNG_ColourType_Indexed :
1689 		{
1690 			switch(IHDR->BitDepth)
1691 			{
1692 				case PNG_BitDepth_1 :
1693 				case PNG_BitDepth_2 :
1694 				case PNG_BitDepth_4 :
1695 				{
1696 					BytesPerPixel    = 1;
1697 					PixelsPerByte    = 8 / IHDR->BitDepth;
1698 
1699 					break;
1700 				}
1701 
1702 				case PNG_BitDepth_8 :
1703 				{
1704 					BytesPerPixel    = PNG_NumColourComponents_Indexed;
1705 					PixelsPerByte    = 1;
1706 
1707 					break;
1708 				}
1709 
1710 				default :
1711 				{
1712 					return(qfalse);
1713 				}
1714 			}
1715 
1716 			break;
1717 		}
1718 
1719 		case PNG_ColourType_GreyAlpha :
1720 		{
1721 			switch(IHDR->BitDepth)
1722 			{
1723 				case PNG_BitDepth_8 :
1724 				case PNG_BitDepth_16 :
1725 				{
1726 					BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_GreyAlpha;
1727 					PixelsPerByte    = 1;
1728 
1729 					break;
1730 				}
1731 
1732 				default :
1733 				{
1734 					return(qfalse);
1735 				}
1736 			}
1737 
1738 			break;
1739 		}
1740 
1741 		case PNG_ColourType_TrueAlpha :
1742 		{
1743 			switch(IHDR->BitDepth)
1744 			{
1745 				case PNG_BitDepth_8 :
1746 				case PNG_BitDepth_16 :
1747 				{
1748 					BytesPerPixel    = (IHDR->BitDepth / 8) * PNG_NumColourComponents_TrueAlpha;
1749 					PixelsPerByte    = 1;
1750 
1751 					break;
1752 				}
1753 
1754 				default :
1755 				{
1756 					return(qfalse);
1757 				}
1758 			}
1759 
1760 			break;
1761 		}
1762 
1763 		default :
1764 		{
1765 			return(qfalse);
1766 		}
1767 	}
1768 
1769 	/*
1770 	 *  Calculate the size of the scanlines per pass
1771 	 */
1772 
1773 	for(a = 0; a < PNG_Adam7_NumPasses; a++)
1774 	{
1775 		BytesPerScanline[a] = (PassWidth[a] * BytesPerPixel + (PixelsPerByte - 1)) / PixelsPerByte;
1776 	}
1777 
1778 	/*
1779 	 *  Calculate the size of all passes
1780 	 */
1781 
1782 	TargetLength = 0;
1783 
1784 	for(a = 0; a < PNG_Adam7_NumPasses; a++)
1785 	{
1786 		TargetLength += ((BytesPerScanline[a] + (BytesPerScanline[a] ? 1 : 0)) * PassHeight[a]);
1787 	}
1788 
1789 	/*
1790 	 *  Check if we have enough data for the whole image.
1791 	 */
1792 
1793 	if(!(DecompressedDataLength == TargetLength))
1794 	{
1795 		return(qfalse);
1796 	}
1797 
1798 	/*
1799 	 *  Unfilter the image.
1800 	 */
1801 
1802 	DecompPtr = DecompressedData;
1803 
1804 	for(a = 0; a < PNG_Adam7_NumPasses; a++)
1805 	{
1806 		if(!UnfilterImage(DecompPtr, PassHeight[a], BytesPerScanline[a], BytesPerPixel))
1807 		{
1808 			return(qfalse);
1809 		}
1810 
1811 		DecompPtr += ((BytesPerScanline[a] + (BytesPerScanline[a] ? 1 : 0)) * PassHeight[a]);
1812 	}
1813 
1814 	/*
1815 	 *  Set the working pointers to the beginning of the buffers.
1816 	 */
1817 
1818 	DecompPtr = DecompressedData;
1819 
1820 	/*
1821 	 *  Create the output image.
1822 	 */
1823 
1824 	for(a = 0; a < PNG_Adam7_NumPasses; a++)
1825 	{
1826 		for(h = 0; h < PassHeight[a]; h++)
1827 		{
1828 			/*
1829 			 *  Count the pixels on the scanline for those multipixel bytes
1830 			 */
1831 
1832 			uint32_t CurrPixel;
1833 
1834 			/*
1835 			 *  skip FilterType
1836 			 *  but only when the pass has a width bigger than zero
1837 			 */
1838 
1839 			if(BytesPerScanline[a])
1840 			{
1841 				DecompPtr++;
1842 			}
1843 
1844 			/*
1845 			 *  Reset the pixel count.
1846 			 */
1847 
1848 			CurrPixel = 0;
1849 
1850 			for(w = 0; w < (BytesPerScanline[a] / BytesPerPixel); w++)
1851 			{
1852 				if(PixelsPerByte > 1)
1853 				{
1854 					uint8_t  Mask;
1855 					uint32_t Shift;
1856 					uint8_t  SinglePixel;
1857 
1858 					for(p = 0; p < PixelsPerByte; p++)
1859 					{
1860 						if(CurrPixel < PassWidth[a])
1861 						{
1862 							Mask  = (1 << IHDR->BitDepth) - 1;
1863 							Shift = (PixelsPerByte - 1 - p) * IHDR->BitDepth;
1864 
1865 							SinglePixel = ((DecompPtr[0] & (Mask << Shift)) >> Shift);
1866 
1867 							OutPtr = OutBuffer + (((((h * HSkip[a]) + HOffset[a]) * IHDR_Width) + ((CurrPixel * WSkip[a]) + WOffset[a])) * Q3IMAGE_BYTESPERPIXEL);
1868 
1869 							if(!ConvertPixel(IHDR, OutPtr, &SinglePixel, HasTransparentColour, TransparentColour, OutPal))
1870 							{
1871 								return(qfalse);
1872 							}
1873 
1874 							CurrPixel++;
1875 						}
1876 					}
1877 
1878 				}
1879 				else
1880 				{
1881 					OutPtr = OutBuffer + (((((h * HSkip[a]) + HOffset[a]) * IHDR_Width) + ((w * WSkip[a]) + WOffset[a])) * Q3IMAGE_BYTESPERPIXEL);
1882 
1883 					if(!ConvertPixel(IHDR, OutPtr, DecompPtr, HasTransparentColour, TransparentColour, OutPal))
1884 					{
1885 						return(qfalse);
1886 					}
1887 				}
1888 
1889 				DecompPtr += BytesPerPixel;
1890 			}
1891 		}
1892 	}
1893 
1894 	return(qtrue);
1895 }
1896 
1897 /*
1898  *  The PNG loader
1899  */
1900 
R_LoadPNG(const char * name,byte ** pic,int * width,int * height,byte alphaByte)1901 void R_LoadPNG(const char *name, byte **pic, int *width, int *height, byte alphaByte)
1902 {
1903 	struct BufferedFile *ThePNG;
1904 	byte *OutBuffer;
1905 	uint8_t *Signature;
1906 	struct PNG_ChunkHeader *CH;
1907 	uint32_t ChunkHeaderLength;
1908 	uint32_t ChunkHeaderType;
1909 	struct PNG_Chunk_IHDR *IHDR;
1910 	uint32_t IHDR_Width;
1911 	uint32_t IHDR_Height;
1912 	PNG_ChunkCRC *CRC;
1913 	uint8_t *InPal;
1914 	uint8_t *DecompressedData;
1915 	uint32_t DecompressedDataLength;
1916 	uint32_t i;
1917 
1918 	/*
1919 	 *  palette with 256 RGBA entries
1920 	 */
1921 
1922 	uint8_t OutPal[1024];
1923 
1924 	/*
1925 	 *  transparent colour from the tRNS chunk
1926 	 */
1927 
1928 	qboolean HasTransparentColour = qfalse;
1929 	uint8_t TransparentColour[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1930 
1931 	/*
1932 	 *  input verification
1933 	 */
1934 
1935 	if(!(name && pic))
1936 	{
1937 		return;
1938 	}
1939 
1940 	/*
1941 	 *  Zero out return values.
1942 	 */
1943 
1944 	*pic = NULL;
1945 
1946 	if(width)
1947 	{
1948 		*width = 0;
1949 	}
1950 
1951 	if(height)
1952 	{
1953 		*height = 0;
1954 	}
1955 
1956 	/*
1957 	 *  Read the file.
1958 	 */
1959 
1960 	ThePNG = ReadBufferedFile(name);
1961 	if(!ThePNG)
1962 	{
1963 		return;
1964 	}
1965 
1966 	/*
1967 	 *  Read the siganture of the file.
1968 	 */
1969 
1970 	Signature = BufferedFileRead(ThePNG, PNG_Signature_Size);
1971 	if(!Signature)
1972 	{
1973 		CloseBufferedFile(ThePNG);
1974 
1975 		return;
1976 	}
1977 
1978 	/*
1979 	 *  Is it a PNG?
1980 	 */
1981 
1982 	if(memcmp(Signature, PNG_Signature, PNG_Signature_Size))
1983 	{
1984 		CloseBufferedFile(ThePNG);
1985 
1986 		return;
1987 	}
1988 
1989 	/*
1990 	 *  Read the first chunk-header.
1991 	 */
1992 
1993 	CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size);
1994 	if(!CH)
1995 	{
1996 		CloseBufferedFile(ThePNG);
1997 
1998 		return;
1999 	}
2000 
2001 	/*
2002 	 *  PNG multi-byte types are in Big Endian
2003 	 */
2004 
2005 	ChunkHeaderLength = BigLong(CH->Length);
2006 	ChunkHeaderType   = BigLong(CH->Type);
2007 
2008 	/*
2009 	 *  Check if the first chunk is an IHDR.
2010 	 */
2011 
2012 	if(!((ChunkHeaderType == PNG_ChunkType_IHDR) && (ChunkHeaderLength == PNG_Chunk_IHDR_Size)))
2013 	{
2014 		CloseBufferedFile(ThePNG);
2015 
2016 		return;
2017 	}
2018 
2019 	/*
2020 	 *  Read the IHDR.
2021 	 */
2022 
2023 	IHDR = BufferedFileRead(ThePNG, PNG_Chunk_IHDR_Size);
2024 	if(!IHDR)
2025 	{
2026 		CloseBufferedFile(ThePNG);
2027 
2028 		return;
2029 	}
2030 
2031 	/*
2032 	 *  Read the CRC for IHDR
2033 	 */
2034 
2035 	CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size);
2036 	if(!CRC)
2037 	{
2038 		CloseBufferedFile(ThePNG);
2039 
2040 		return;
2041 	}
2042 
2043 	/*
2044 	 *  Here we could check the CRC if we wanted to.
2045 	 */
2046 
2047 	/*
2048 	 *  multi-byte type swapping
2049 	 */
2050 
2051 	IHDR_Width  = BigLong(IHDR->Width);
2052 	IHDR_Height = BigLong(IHDR->Height);
2053 
2054 	/*
2055 	 *  Check if Width and Height are valid.
2056 	 */
2057 
2058 	if(!((IHDR_Width > 0) && (IHDR_Height > 0))
2059 	|| IHDR_Width > INT_MAX / Q3IMAGE_BYTESPERPIXEL / IHDR_Height)
2060 	{
2061 		CloseBufferedFile(ThePNG);
2062 
2063 		Com_Printf(S_COLOR_YELLOW "%s: invalid image size\n", name);
2064 
2065 		return;
2066 	}
2067 
2068 	/*
2069 	 *  Do we need to check if the dimensions of the image are valid for Quake3?
2070 	 */
2071 
2072 	/*
2073 	 *  Check if CompressionMethod and FilterMethod are valid.
2074 	 */
2075 
2076 	if(!((IHDR->CompressionMethod == PNG_CompressionMethod_0) && (IHDR->FilterMethod == PNG_FilterMethod_0)))
2077 	{
2078 		CloseBufferedFile(ThePNG);
2079 
2080 		return;
2081 	}
2082 
2083 	/*
2084 	 *  Check if InterlaceMethod is valid.
2085 	 */
2086 
2087 	if(!((IHDR->InterlaceMethod == PNG_InterlaceMethod_NonInterlaced)  || (IHDR->InterlaceMethod == PNG_InterlaceMethod_Interlaced)))
2088 	{
2089 		CloseBufferedFile(ThePNG);
2090 
2091 		return;
2092 	}
2093 
2094 	/*
2095 	 *  Read palette for an indexed image.
2096 	 */
2097 
2098 	if(IHDR->ColourType == PNG_ColourType_Indexed)
2099 	{
2100 		/*
2101 		 *  We need the palette first.
2102 		 */
2103 
2104 		if(!FindChunk(ThePNG, PNG_ChunkType_PLTE))
2105 		{
2106 			CloseBufferedFile(ThePNG);
2107 
2108 			return;
2109 		}
2110 
2111 		/*
2112 		 *  Read the chunk-header.
2113 		 */
2114 
2115 		CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size);
2116 		if(!CH)
2117 		{
2118 			CloseBufferedFile(ThePNG);
2119 
2120 			return;
2121 		}
2122 
2123 		/*
2124 		 *  PNG multi-byte types are in Big Endian
2125 		 */
2126 
2127 		ChunkHeaderLength = BigLong(CH->Length);
2128 		ChunkHeaderType   = BigLong(CH->Type);
2129 
2130 		/*
2131 		 *  Check if the chunk is an PLTE.
2132 		 */
2133 
2134 		if(!(ChunkHeaderType == PNG_ChunkType_PLTE))
2135 		{
2136 			CloseBufferedFile(ThePNG);
2137 
2138 			return;
2139 		}
2140 
2141 		/*
2142 		 *  Check if Length is divisible by 3
2143 		 */
2144 
2145 		if(ChunkHeaderLength % 3)
2146 		{
2147 			CloseBufferedFile(ThePNG);
2148 
2149 			return;
2150 		}
2151 
2152 		/*
2153 		 *  Read the raw palette data
2154 		 */
2155 
2156 		InPal = BufferedFileRead(ThePNG, ChunkHeaderLength);
2157 		if(!InPal)
2158 		{
2159 			CloseBufferedFile(ThePNG);
2160 
2161 			return;
2162 		}
2163 
2164 		/*
2165 		 *  Read the CRC for the palette
2166 		 */
2167 
2168 		CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size);
2169 		if(!CRC)
2170 		{
2171 			CloseBufferedFile(ThePNG);
2172 
2173 			return;
2174 		}
2175 
2176 		/*
2177 		 *  Set some default values.
2178 		 */
2179 
2180 		for(i = 0; i < 256; i++)
2181 		{
2182 			OutPal[i * Q3IMAGE_BYTESPERPIXEL + 0] = 0x00;
2183 			OutPal[i * Q3IMAGE_BYTESPERPIXEL + 1] = 0x00;
2184 			OutPal[i * Q3IMAGE_BYTESPERPIXEL + 2] = 0x00;
2185 			OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = 0xFF;
2186 		}
2187 
2188 		/*
2189 		 *  Convert to the Quake3 RGBA-format.
2190 		 */
2191 
2192 		for(i = 0; i < (ChunkHeaderLength / 3); i++)
2193 		{
2194 			OutPal[i * Q3IMAGE_BYTESPERPIXEL + 0] = InPal[i*3+0];
2195 			OutPal[i * Q3IMAGE_BYTESPERPIXEL + 1] = InPal[i*3+1];
2196 			OutPal[i * Q3IMAGE_BYTESPERPIXEL + 2] = InPal[i*3+2];
2197 			OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = 0xFF;
2198 		}
2199 	}
2200 
2201 	/*
2202 	 *  transparency information is sometimes stored in an tRNS chunk
2203 	 */
2204 
2205 	/*
2206 	 *  Let's see if there is a tRNS chunk
2207 	 */
2208 
2209 	if(FindChunk(ThePNG, PNG_ChunkType_tRNS))
2210 	{
2211 		uint8_t *Trans;
2212 
2213 		/*
2214 		 *  Read the chunk-header.
2215 		 */
2216 
2217 		CH = BufferedFileRead(ThePNG, PNG_ChunkHeader_Size);
2218 		if(!CH)
2219 		{
2220 			CloseBufferedFile(ThePNG);
2221 
2222 			return;
2223 		}
2224 
2225 		/*
2226 		 *  PNG multi-byte types are in Big Endian
2227 		 */
2228 
2229 		ChunkHeaderLength = BigLong(CH->Length);
2230 		ChunkHeaderType   = BigLong(CH->Type);
2231 
2232 		/*
2233 		 *  Check if the chunk is an tRNS.
2234 		 */
2235 
2236 		if(!(ChunkHeaderType == PNG_ChunkType_tRNS))
2237 		{
2238 			CloseBufferedFile(ThePNG);
2239 
2240 			return;
2241 		}
2242 
2243 		/*
2244 		 *  Read the transparency information.
2245 		 */
2246 
2247 		Trans = BufferedFileRead(ThePNG, ChunkHeaderLength);
2248 		if(!Trans)
2249 		{
2250 			CloseBufferedFile(ThePNG);
2251 
2252 			return;
2253 		}
2254 
2255 		/*
2256 		 *  Read the CRC.
2257 		 */
2258 
2259 		CRC = BufferedFileRead(ThePNG, PNG_ChunkCRC_Size);
2260 		if(!CRC)
2261 		{
2262 			CloseBufferedFile(ThePNG);
2263 
2264 			return;
2265 		}
2266 
2267 		/*
2268 		 *  Only for Grey, True and Indexed ColourType should tRNS exist.
2269 		 */
2270 
2271 		switch(IHDR->ColourType)
2272 		{
2273 			case PNG_ColourType_Grey :
2274 			{
2275 				if(!ChunkHeaderLength == 2)
2276 				{
2277 					CloseBufferedFile(ThePNG);
2278 
2279 					return;
2280 				}
2281 
2282 				HasTransparentColour = qtrue;
2283 
2284 				/*
2285 				 *  Grey can have one colour which is completely transparent.
2286 				 *  This colour is always stored in 16 bits.
2287 				 */
2288 
2289 				TransparentColour[0] = Trans[0];
2290 				TransparentColour[1] = Trans[1];
2291 
2292 				break;
2293 			}
2294 
2295 			case PNG_ColourType_True :
2296 			{
2297 				if(!ChunkHeaderLength == 6)
2298 				{
2299 					CloseBufferedFile(ThePNG);
2300 
2301 					return;
2302 				}
2303 
2304 				HasTransparentColour = qtrue;
2305 
2306 				/*
2307 				 *  True can have one colour which is completely transparent.
2308 				 *  This colour is always stored in 16 bits.
2309 				 */
2310 
2311 				TransparentColour[0] = Trans[0];
2312 				TransparentColour[1] = Trans[1];
2313 				TransparentColour[2] = Trans[2];
2314 				TransparentColour[3] = Trans[3];
2315 				TransparentColour[4] = Trans[4];
2316 				TransparentColour[5] = Trans[5];
2317 
2318 				break;
2319 			}
2320 
2321 			case PNG_ColourType_Indexed :
2322 			{
2323 				/*
2324 				 *  Maximum of 256 one byte transparency entries.
2325 				 */
2326 
2327 				if(ChunkHeaderLength > 256)
2328 				{
2329 					CloseBufferedFile(ThePNG);
2330 
2331 					return;
2332 				}
2333 
2334 				HasTransparentColour = qtrue;
2335 
2336 				/*
2337 				 *  alpha values for palette entries
2338 				 */
2339 
2340 				for(i = 0; i < ChunkHeaderLength; i++)
2341 				{
2342 					OutPal[i * Q3IMAGE_BYTESPERPIXEL + 3] = Trans[i];
2343 				}
2344 
2345 				break;
2346 			}
2347 
2348 			/*
2349 			 *  All other ColourTypes should not have tRNS chunks
2350 			 */
2351 
2352 			default :
2353 			{
2354 				CloseBufferedFile(ThePNG);
2355 
2356 				return;
2357 			}
2358 		}
2359 	}
2360 
2361 	/*
2362 	 *  Rewind to the start of the file.
2363 	 */
2364 
2365 	if(!BufferedFileRewind(ThePNG, -1))
2366 	{
2367 		CloseBufferedFile(ThePNG);
2368 
2369 		return;
2370 	}
2371 
2372 	/*
2373 	 *  Skip the signature
2374 	 */
2375 
2376 	if(!BufferedFileSkip(ThePNG, PNG_Signature_Size))
2377 	{
2378 		CloseBufferedFile(ThePNG);
2379 
2380 		return;
2381 	}
2382 
2383 	/*
2384 	 *  Decompress all IDAT chunks
2385 	 */
2386 
2387 	DecompressedDataLength = DecompressIDATs(ThePNG, &DecompressedData);
2388 	if(!(DecompressedDataLength && DecompressedData))
2389 	{
2390 		CloseBufferedFile(ThePNG);
2391 
2392 		return;
2393 	}
2394 
2395 	/*
2396 	 *  Allocate output buffer.
2397 	 */
2398 
2399 	OutBuffer = ri.Malloc(IHDR_Width * IHDR_Height * Q3IMAGE_BYTESPERPIXEL);
2400 	if(!OutBuffer)
2401 	{
2402 		ri.Free(DecompressedData);
2403 		CloseBufferedFile(ThePNG);
2404 
2405 		return;
2406 	}
2407 
2408 	/*
2409 	 *  Interlaced and Non-interlaced images need to be handled differently.
2410 	 */
2411 
2412 	switch(IHDR->InterlaceMethod)
2413 	{
2414 		case PNG_InterlaceMethod_NonInterlaced :
2415 		{
2416 			if(!DecodeImageNonInterlaced(IHDR, OutBuffer, DecompressedData, DecompressedDataLength, HasTransparentColour, TransparentColour, OutPal))
2417 			{
2418 				ri.Free(OutBuffer);
2419 				ri.Free(DecompressedData);
2420 				CloseBufferedFile(ThePNG);
2421 
2422 				return;
2423 			}
2424 
2425 			break;
2426 		}
2427 
2428 		case PNG_InterlaceMethod_Interlaced :
2429 		{
2430 			if(!DecodeImageInterlaced(IHDR, OutBuffer, DecompressedData, DecompressedDataLength, HasTransparentColour, TransparentColour, OutPal))
2431 			{
2432 				ri.Free(OutBuffer);
2433 				ri.Free(DecompressedData);
2434 				CloseBufferedFile(ThePNG);
2435 
2436 				return;
2437 			}
2438 
2439 			break;
2440 		}
2441 
2442 		default :
2443 		{
2444 			ri.Free(OutBuffer);
2445 			ri.Free(DecompressedData);
2446 			CloseBufferedFile(ThePNG);
2447 
2448 			return;
2449 		}
2450 	}
2451 
2452 	/*
2453 	 *  update the pointer to the image data
2454 	 */
2455 
2456 	*pic = OutBuffer;
2457 
2458 	/*
2459 	 *  Fill width and height.
2460 	 */
2461 
2462 	if(width)
2463 	{
2464 		*width = IHDR_Width;
2465 	}
2466 
2467 	if(height)
2468 	{
2469 		*height = IHDR_Height;
2470 	}
2471 
2472 	/*
2473 	 *  DecompressedData is not needed anymore.
2474 	 */
2475 
2476 	ri.Free(DecompressedData);
2477 
2478 	/*
2479 	 *  We have all data, so close the file.
2480 	 */
2481 
2482 	CloseBufferedFile(ThePNG);
2483 }
2484