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