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