display-name: "Images/PCX"

file-format image-PCX
{
	unsigned8 ManufactureByte
	unsigned8 Version
	unsigned8 RLE
	unsigned8 BitsPerPixel
	unsigned16 Xmin
	unsigned16 Ymin
	unsigned16 Xmax
	unsigned16 Ymax
	unsigned16 hDPI
	unsigned16 vDPI

	palette
	{
		size: 16
		format: "R8G8B8" //will get overriden if 256 color later on
	}

	unsigned8 reserved
	unsigned8 planeCount
	unsigned16 memoryPerRow
	unsigned16 paletteInterpret
	unsigned16 hRes
	unsigned16 vRes
	data(54) reserved2

	width: Xmax - Xmin + 1
	height: Ymax - Ymin + 1

	totalBytesPerRow: memoryPerRow * planeCount

	EightBitImage: false

	if (Version == 5 and file.size >= 769)
	{		
		at file.size - 769
		{
			unsigned8 EightBitID
			if (EightBitID == 12)
			{
				EightBitImage: true
				palette
				{
					size: 256
					format: "R8G8B8"
				}
			}
		}
	}
	
	if (EightBitImage != true)
	{
		SizeToRead: file.remaining-bytes
	}
	else
	{
		SizeToRead: file.remaining-bytes - 769
	}

	/*if (((BitsPerPixel * planeCount) == 2) and (EightBitImage == false))
	{
		palette[0] = palette[0] >> 4
		palette[1] = palette[1] >> 4
		palette[2] = palette[2] >> 4
	}*/

	compressed [SizeToRead] "PCXRLE"
	{
		if (EightBitImage == true)
		{
			image
			{
				format: "I8"
				stride: (totalBytesPerRow * 8) / (planeCount * BitsPerPixel)
			}			
		}
		else
		{
			image
			{
				format: "I" + (planeCount * BitsPerPixel)
				bit-stride: (totalBytesPerRow * 8) / (planeCount * BitsPerPixel)
				stride: bit-stride

				if ((planeCount * BitsPerPixel) == 2)
				{
					bit-stride: 1
				}
				
			}
		}		
	}
	/*file[1]
	{
		offset: file.position
		name: "pcx-data"
		size: SizeToRead
		compressed "PCXRLE"
	}*/
}

function PCXRLE
{
	loop (height)
	{
		//no way to do this...
		//decompressed.seek(y * totalBytes);
		running: 0

		loop while (running < totalBytesPerRow)
		{
			read unsigned8 thisByte

			if (thisByte >= 192)   //rle
			{
				read unsigned8 nextByte
				fill(amount: (thisByte & 0x3F), value: nextByte)
				running = running + (thisByte & 0x3F)
			}
			else
			{				
				write unsigned8 thisByte
				running = running + 1
			}
		}		
	}
}


if (file.name like "*.*")
{
	interpret-as "image-PCX"
}