A little help, if you could spare your time - firstly, a big box o' code:
Don't get too scared about all that, there's only a couple of small sections I need help with : revolving around my use of the ColourMap:ColourRegister[] Global. What I'm trying to do with it, is keep an array of red, green, blue information available to the loader method in between calls. Looking at the code up there it doesn't make any sense to do it this way, but I'll be expanding on that later. If you jump down to the "CMAP" section, what it does is this : If a ColourMap array doesn't exist (ie it's Null), it creates an array of the size of the CMAP chunk (the number of colours in the palette table) - then when it comes time to setting the values in the array, it errors out with 'trying to access field of Null object'.
Which is fine, my head isn't coping very well with all this, but I managed to figure out that each entry in the array needs initialising as well, being that it's a custom type. But if you unRem the ColourMap line in that loop, I still have problems at the bottom of the method - scroll down to the pixmap.WritePixel line. Here, again, I get complaints that I'm referencing a Null object, which I thouroughly don't understand, it was created and set when I processed the CMAP entry - why can't I access it now?
It's supposed to be Global so there shouldn't be any problems from what I can tell. Any ideas would be immensely appreciated.
Oh, if you need an example file to use this on for whatever reason, grab one at http://members.dodo.com.au/~tzuyd/bull.iff - it's a small 5x5 graphic with a palette of 16 colours.
Oh and there's every possibility that even if the ColourMap stuff was working, that the graphic would look completely corrupted, so don't worry about that ;]
Strict Rem bbdoc: IFF ILBM loader End Rem Module HOT.IFFILBMLoader ModuleInfo "Version: 1.00" ModuleInfo "Author: Toby Zuijdveld" ModuleInfo "License: Blitz Shared Source Code" ModuleInfo "Copyright: Jerry Morrison, Electronic Arts (public domain)" ModuleInfo "Modserver: n/a" ModuleInfo "History: 1.00 Release" Import BRL.Pixmap Import BRL.EndianStream Private Function ReadTag$( stream:TStream ) Local tag:Byte[4] If stream.ReadBytes( tag,4 )<>4 Return Return Chr(tag[0])+Chr(tag[1])+Chr(tag[2])+Chr(tag[3]) End Function Function UStoSI%(a:Short) If a>$7FFF Then Return -($8000-(a-$8000)) Else Return a End Function ' unsigned short to signed integer Const cmpNone = 0 Const cmpByteRun1 = 1 Type ColourRegister Field red:Byte Field green:Byte Field blue:Byte ' colour intensities 0..255 End Type ' size = 3 bytes Global ColourMap:ColourRegister[] = Null Public Type TPixmapLoaderILBM Extends TPixmapLoader Method LoadPixmap:TPixmap(stream:TStream) stream=BigEndianStream( stream ) If ReadTag( stream )<>"FORM" Return Local dud% = stream.Readint() ' length of file after ILBM header If ReadTag( stream )<>"ILBM" Return Local cmap% = 0 Local w:Short = 0 Local h:Short = 0 Local x% = 0 Local y% = 0 Local nPlanes:Byte = 0 Local masking:Byte = 0 Local compression:Byte = 0 Local transparentColour:Short = 0 Local xAspect:Byte = 0 Local yAspect:Byte = 0 Local pageWidth% = 0 Local pageHeight% = 0 Local plane% = 0 Local scanline% = 0 Local i% = 0 Local n% = 0 Local nn% = 0 Local pixmap:TPixmap = Null While Not stream.Eof() Local blahblah$=ReadTag$(stream) Select blahblah$'Readtag$(stream) Case "BMHD" ' BitMapHeader dud = stream.ReadInt() ' length of BitMapHeader chunk w = stream.ReadShort() h = stream.ReadShort() ' raster width & height in pixels x = UStoSI(stream.ReadShort()) y = UStoSI(stream.ReadShort()) ' pixel position for this image nPlanes = stream.ReadByte() ' # source bitplanes masking = stream.ReadByte() ' Choice of masking technique. compression = stream.ReadByte() ' Choice of compression algorithm applied to the rows of all source and mask planes. Local dud2% = stream.ReadByte() ' unused; for consistency, put 0 here transparentColour = stream.ReadShort() ' transparent "colour number" (sort of) xAspect = stream.ReadByte() yAspect = stream.ReadByte() ' pixel aspect, a ratio width : height pageWidth = UStoSI(stream.ReadShort()) pageHeight = UStoSI(stream.ReadShort()) ' source "page" size in pixels stream.SkipBytes(dud-20) ' extended chunk compatibility Case "CMAP" ' ColorMap dud = stream.ReadInt() ' length of ColourMap chunk If ColourMap=Null cmap = dud/3 ColourMap = New ColourRegister[cmap+1] ' size = (2^nPlanes)*3 bytes For i=1 To cmap ' ColourMap[i] = New ColourRegister ColourMap[i].red = stream.ReadByte() ColourMap[i].green = stream.ReadByte() ColourMap[i].blue = stream.ReadByte() Next If dud & 1 Then stream.SkipBytes(1) ' padded chunk compatibility Else stream.SkipBytes(dud) ' skip chunk EndIf ' ColourMap=Null Case "BODY" ' dud = stream.ReadInt() ' length of BODY chunk Local row%[w+9] Local buffer%[9] pixmap = TPixmap.Create(w,h,PF_RGB888) If 2^nPlanes>cmap Then ColourMap=ColourMap[..(2^nPlanes)+1] For Local column%=1 To h row = New Int[w+9] Select compression Case cmpNone For plane=1 To nPlanes For scanline=1 To w Step 8 buffer[1] = stream.ReadByte() For dud=2 To 8 buffer[dud] = (buffer[1] Shr (dud-1)) & 1 Next ' dud=2 To 8 buffer[1] = buffer[1] & 1 For dud=1 To 8 row[scanline+(dud-1)] = row[scanline+(dud-1)]+(buffer[dud] Shl (plane-1)) Next ' dud=1 To 8 Next ' scanline=1 To w Step 8 Next ' plane=1 To nPlanes Case cmpByteRun1 For plane=1 To nPlanes scanline = 1 Repeat dud=stream.ReadByte() If dud>127 Then dud:-256 ' unsigned to signed conversion If dud<>-128 ' noop If dud<0 ' replicate the next byte -n+1 times dud = Abs(dud)+1 n = stream.ReadByte() buffer[1] = n For nn=2 To 8 buffer[nn] = (buffer[1] Shr (nn-1)) & 1 Next ' nn=2 To 8 buffer[1] = buffer[1] & 1 For i=1 To dud For nn=1 To 8 row[scanline+(nn-1)+((i-1)*8)] = row[scanline+(nn-1)+((i-1)*8)]+(buffer[nn] Shl (plane-1)) Next ' nn=1 To 8 Next ' i%=1 To dud scanline:+dud Else ' copy the next n+1 bytes literally For nn=1 To dud+1 n = stream.ReadByte() buffer[1] = n For nn%=2 To 8 buffer[nn] = (buffer[1] Shr (nn-1)) & 1 Next ' nn=2 To 8 buffer[1] = buffer[1] & 1 For i=1 To 8 row[scanline+(i-1)] = row[scanline+(i-1)]+(buffer[i] Shl (plane-1)) Next ' i=1 To 8 scanline:+1 Next ' nn=1 To dud+1 EndIf EndIf Until scanline>w Next ' plane=1 To nPlanes Default ' unsupported compression algorithm dud = 0 Exit End Select ' compression debugstop If dud=0 Then pixmap = Null;Exit For dud=1 To w pixmap.WritePixel dud-1,column-1,(ColourMap[row[dud]].red Shl 16)+(ColourMap[row[dud]].green Shl 8)+ColourMap[row[dud]].blue Next ' row=1 To w Next ' column=1 To h If cmap Then ColourMap = Null Exit Default ' unsupported chunks stream.SkipBytes(stream.ReadInt()) ' skip chunk End Select ' ReadTag$(stream) If pixmap Then Exit Wend ' Not stream.EOF() Return pixmap End Method End Type New TPixmapLoaderILBM
Don't get too scared about all that, there's only a couple of small sections I need help with : revolving around my use of the ColourMap:ColourRegister[] Global. What I'm trying to do with it, is keep an array of red, green, blue information available to the loader method in between calls. Looking at the code up there it doesn't make any sense to do it this way, but I'll be expanding on that later. If you jump down to the "CMAP" section, what it does is this : If a ColourMap array doesn't exist (ie it's Null), it creates an array of the size of the CMAP chunk (the number of colours in the palette table) - then when it comes time to setting the values in the array, it errors out with 'trying to access field of Null object'.
Which is fine, my head isn't coping very well with all this, but I managed to figure out that each entry in the array needs initialising as well, being that it's a custom type. But if you unRem the ColourMap line in that loop, I still have problems at the bottom of the method - scroll down to the pixmap.WritePixel line. Here, again, I get complaints that I'm referencing a Null object, which I thouroughly don't understand, it was created and set when I processed the CMAP entry - why can't I access it now?
It's supposed to be Global so there shouldn't be any problems from what I can tell. Any ideas would be immensely appreciated.
Oh, if you need an example file to use this on for whatever reason, grab one at http://members.dodo.com.au/~tzuyd/bull.iff - it's a small 5x5 graphic with a palette of 16 colours.
Oh and there's every possibility that even if the ColourMap stuff was working, that the graphic would look completely corrupted, so don't worry about that ;]