Loading PCX Images?

Blitz3D Forums/Blitz3D Userlibs/Loading PCX Images?

Blaine(Posted 2005) [#1]
(This is really for a BlitzPlus project, but it goes for Blitz3D just as much and there isn't any BlitzPlus userlib forum)

Hello, all! I was wondering if a userlib to read image formats such as psd, tif, pcx, etc. exists and if so where I can find it? I'm pretty sure that one exists, but I can't find it anywhere. Here's what I need:
- The ability to load PCX images (8-bit ones)
- The ability to read palette entries in 8-bit PCX images*
- The ability to display the PCX images

* = Not mission-critical, but still wanted

Or, if no such userlib exists, could anyone code something that could do these things for me, or at least help me do so (I don't even know where to start if I have to do that)? I'm hoping to have this project done soon, so any help on the matter would be appreciated. Thanks for your time!

-Blaine


jfk EO-11110(Posted 2005) [#2]
I guess not PSD since it's a complex format. TIF may be easy, (maybe there is already one in the code archives?) and I remember PCX already worls for textures, if I remember right. (Wasn't the runner demo using a PCX Texture?). In BLitz3D you could load it as a texture and then copyrect to a imagebuffer. Tho not sure how to do it in Blitz+. But I think PCX is a simple format too. Just get the format description, must be somewhere in the web.


Snarkbait(Posted 2005) [#3]
Blitz3d does loads and displays .pcx images (not listed in the docs but I just tested it), not sure why b+ doesn't seem to.


Blaine(Posted 2005) [#4]
Blitz3D does it? Wow, I never knew that. I do have Blitz3D as well as BlitzPlus, so I suppose I could work something out with that if I need to...

-Blaine


Snarkbait(Posted 2005) [#5]
it wouldn't be too hard to do a blitz+ loader, I was looking in to the specs last night but it got too late, fairly simple file spec though.


Blaine(Posted 2005) [#6]
Yeah, it doesn't look incredibly complex. I found a site where they have the specs for it, so I'll try my hand at programming a PCX loading function in BlitzPlus...

-Blaine


Snarkbait(Posted 2005) [#7]
Here you go: this only will work on 256-color 8-bit pcx images, and only needed for blitz plus as shown above..

include file:
;loadpcxfile.bb include
;blitz plus only, not needed for b3d
; only for 8-bit color pcx images

Dim pallette256(255,2)

Function loadPCXimage(image$)
	pcxfile = ReadFile(image$)
	If Not pcxfile RuntimeError "file not found"
	size = FileSize(image$)
	ident = ReadByte(pcxfile) ;should be 10
	version = ReadByte(pcxfile);should be 5
	encoding = ReadByte(pcxfile) ; should be 1
	bits_per_pixel = ReadByte(pcxfile)
	xmin = ReadShort(pcxfile)
	ymin = ReadShort(pcxfile)
	xmax = ReadShort(pcxfile)
	ymax = ReadShort(pcxfile)
	xsize = xmax - xmin + 1
	ysize = ymax - ymin + 1
	SeekFile(pcxfile,65)
	Nplanes = ReadByte(pcxfile)
	bytes_per_line = ReadShort(pcxfile)
	totalbytes = Nplanes * bytes_per_line
	; go to pallette header
	SeekFile(pcxfile,size - 769)
	a = ReadByte(pcxfile)
	If a = 12
		;read pallette
		For color_value = 0 To 255
			For RGB = 0 To 2
				readval = ReadByte(pcxfile)
				pallette256(color_value,RGB) = readval ;Shr 2
				;DebugLog pallette256(color_value,RGB)
			Next
		Next 
	EndIf
	SeekFile(pcxfile,128)
	newimage = CreateImage(xsize,ysize)
	SetBuffer ImageBuffer(newimage)
	xcount = 1:ycount = 1
	While Not Eof(pcxfile)
		readval = ReadByte(pcxfile)
		If (readval And $C0) = $C0

			pcnt = readval And $3F
			readval = ReadByte(pcxfile)
			For a = 1 To pcnt
				WritePixel xcount-1,ycount-1,argb(pallette256(readval,0),pallette256(readval,1),pallette256(readval,2))
				xcount = xcount + 1
				If xcount > totalbytes xcount = 1:ycount = ycount + 1
				If ycount > ysize Exit 
			Next
		Else
			WritePixel xcount-1,ycount-1,argb(pallette256(readval,0),pallette256(readval,1),pallette256(readval,2))
		 	xcount = xcount + 1
			If xcount > totalbytes xcount = 1:ycount = ycount + 1
			If ycount > ysize Exit
		EndIf
	Wend 
	CloseFile pcxfile
	Return newimage
End Function

Function argb(red,green,blue)
	Return (blue Or (green Shl 8) Or (red Shl 16) Or (255 Shl 24))
End Function 



Test file:

Include "loadpcxfile.bb"

Global main = CreateWindow("PCX Loader",0,0,800,600,0,1)
canvas = CreateCanvas(0,0,800,600,main)


this$ = RequestFile$("Open PCX Image","pcx")

convertedimage = loadpcximage(this$)

SetBuffer CanvasBuffer(canvas)
DrawImage convertedimage,0,0
FlipCanvas canvas
WaitKey()
End 



put in the code archives, optimized with writepixelfast here:
http://www.blitzbasic.com/codearcs/codearcs.php?code=1342


Blaine(Posted 2005) [#8]
Great, it works! Thanks a million (I don't know if I could've done that even if I worked on it for days)! I'm hoping I can have this project done soon... it'll be the first Blitz Basic program that I've ever released, so thanks again for helping me out! (I'll be sure to give credit!)

-Blaine


Snarkbait(Posted 2005) [#9]
Cool.. glad I could help you out. Note that the pallette of the image is there in an array if you want to access it, in array 'Pallette256(255,2)' the first number is the color index number 0 - 255 and the second number is for RGB values, R = 0, 1 = G, 2 = B.


EddieRay(Posted 2005) [#10]
Wouldn't the palette array need to be declared as:

Dim Palette(256,3)

in order to have index values from 0..255 and 0..2? I'm a C programmer, and I thought Blitz arrays worked the same way as C...


Snarkbait(Posted 2005) [#11]
Nope. You can dimension them that way if you want, but there will be an unused element.