DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Quake LMP Parser

08.06.2011
| 2312 views |
  • submit to reddit
        Canvas LMP (Quake QPic) parser.
Usage: LMPOpen (file name, canvas element, X pos on canvas, Y pos on canvas, path to palette, subrectangle X, subrectangle Y, subrectangle width, subrectangle height).
function LMPOpen(LMPFileName,LMPTarget,LMPX,LMPY,LMPPaletteFilename,LMPSubX,LMPSubY,LMPSubW,LMPSubH)
{
	if (document.getElementById(LMPTarget) == null) return;
	if (LMPFileName == null) return;
	
	//LMP file request
	var LMPRequest = new XMLHttpRequest();
	LMPRequest.open('GET',LMPFileName,false);
	LMPRequest.overrideMimeType('text/plain;charset=x-user-defined');
	LMPRequest.send(null);
	var LMPFile;
	LMPFile = LMPRequest.responseText;
	LMPRequest.abort();
	
	//Parsing
	var LMPOfs = 0;
	var LMPWidth = 0;
	var LMPHeight = 0;
	
	//Width and height
	LMPWidth = parseInt(
		'0x' + (LMPFile.charCodeAt(LMPOfs+3)&255).toString(16) + 
		(LMPFile.charCodeAt(LMPOfs+2)&255).toString(16) + 
		(LMPFile.charCodeAt(LMPOfs+1)&255).toString(16) + 
		(LMPFile.charCodeAt(LMPOfs)&255).toString(16))
	LMPOfs+=4;
	LMPHeight = parseInt(
		'0x' + (LMPFile.charCodeAt(LMPOfs+3)&255).toString(16) + 
		(LMPFile.charCodeAt(LMPOfs+2)&255).toString(16) + 
		(LMPFile.charCodeAt(LMPOfs+1)&255).toString(16) + 
		(LMPFile.charCodeAt(LMPOfs)&255).toString(16))
	LMPOfs+=4;
	
	//Pixels
	var LMPContext = document.getElementById(LMPTarget).getContext('2d');
	var LMPImageData = LMPContext.createImageData(LMPWidth,LMPHeight);
	//Palette
	var LMPPal;
	var LMPNumColors;
	if (LMPFile[LMPOfs+LMPWidth*LMPHeight] == null)
	{
		var LMPPalRequest = new XMLHttpRequest();
		LMPPalRequest.open('GET',LMPPaletteFilename || 'palette.lmp',false);
		LMPPalRequest.overrideMimeType('text/plain;charset=x-user-defined');
		LMPPalRequest.send(null);
		if ((LMPPalRequest.status == 200) || (LMPPalRequest.status == 0))
			LMPPal = LMPPalRequest.responseText;
		LMPPalRequest.abort();
		LMPNumColors = parseInt(LMPPal.length/3);
	}
	else
	{
		LMPNumColors = LMPFile.charCodeAt(LMPOfs+LMPWidth*LMPHeight)&255;
		if (LMPFile.charCodeAt(1+LMPOfs+LMPWidth*LMPHeight)&255 > 0)
			LMPNumColors = 256;
		LMPPal = LMPFile.substr(2+LMPOfs+LMPWidth*LMPHeight,LMPNumColors*3);
	}
	var LMPColors = [];
	var LMPQPalOfs = 0;
	var iClr = 0;
	for (iClr=0;iClr<LMPNumColors;iClr++)
	{
		LMPColors[iClr] = [];
		var iChan=0;
		for (iChan=0;iChan<3;iChan++)
		{
			LMPColors[iClr][iChan] = LMPPal.charCodeAt(LMPQPalOfs)&255;
			LMPQPalOfs++;
		}
	}
	var i=0;
	for (i=0;i<LMPWidth*LMPHeight;i++)
	{
		if ((LMPFile.charCodeAt(LMPOfs)&255) != 255)
		{
			LMPImageData.data[i*4] = LMPColors[LMPFile.charCodeAt(LMPOfs)&255][0];
			LMPImageData.data[i*4+1] = LMPColors[LMPFile.charCodeAt(LMPOfs)&255][1];
			LMPImageData.data[i*4+2] = LMPColors[LMPFile.charCodeAt(LMPOfs)&255][2];
			LMPImageData.data[i*4+3] = 255;
		}
		LMPOfs++;
	}
	LMPContext.putImageData(LMPImageData, (LMPX||0)-(LMPSubX||0), (LMPY||0)-(LMPSubY||0), LMPSubX||0, LMPSubY||0, LMPSubW||LMPWidth, LMPSubH||LMPHeight);
}