basically, the header of the image is:
Code: Select all
Structure NIF
compression.b
width.l
height.l
sizecompressed.l
sizeuncompressed.l
EndStructure
so i set the structure width, height and compression, and then pack the bitmap bits. i then set the compressed and uncompressed members after packing. i write it all to a file, and call it "NIF - New Image Format"
It actually ends up being very efficient in size reduction and overhead. I also plan to make this format support multiple images like DCX, and even give the ability to store frames of an animated image.
HOWEVER, when i try to decompress the packed bits, PB unpacker fails, as well as "invalid memory access" with BriefLZ and PureZIP.
to decode it i read the header, get the width, height and compression sizes. i allocate the source and destination buffers, and then try to decompress. I setup the bitmapinfo structures, and then createbitmapindirect with the lbvbits set to the *destination buffer of the unpacker. however, ALL unpackers fail.
here is the code. can anyone figure out WHY the packers fail?
Code: Select all
Structure NIF
compression.b
width.l
height.l
sizecompressed.l
sizeuncompressed.l
EndStructure
Procedure SaveNIF(hBitmap.l, filename.s, compression.l)
If OpenFile(0,filename)
GetObject_(hBitmap, SizeOf(BITMAP), bm.BITMAP) ; get our bitmap, imageid(image), loadimage ect
bitcount = bm\bmBitsPixel ; get the bitcount
;Debug bitcount
width=bm\bmWidth
height=bm\bmHeight
extrabytesperrow = (4 - (width * bitcount / 8) % 4) % 4
sizeheaders = SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER)
sizeimage = (width * bitcount / 8 + extrabytesperrow) * height ;calculate the total image size
*bitmap = AllocateMemory(sizeheaders + sizeimage);allocate a memory block
*bitmapfile.BITMAPFILEHEADER = *bitmap ;here we set all out headers
*bitmapfile\bfType = Asc("B") + Asc("M") << 8
*bitmapfile\bfSize = sizeheaders +sizeimage
*bitmapfile\bfOffBits = sizeheaders
*bitmapinfo.BITMAPINFOHEADER = *bitmap + SizeOf(BITMAPFILEHEADER)
*bitmapinfo\biSize = SizeOf(BITMAPINFOHEADER)
*bitmapinfo\biWidth = width
*bitmapinfo\biHeight = height
*bitmapinfo\biPlanes = 1
*bitmapinfo\biBitCount = bitcount
*bitmapinfo\biCompression = 0
*bitmapinfo\biSizeImage = sizeimage
*bitmapdata = *bitmap + sizeheaders ;
hdc = GetDC_(#Null)
GetDIBits_(hdc, hBitmap, 0, height, *bitmap+sizeheaders, *bitmapinfo, #DIB_RGB_COLORS)
ReleaseDC_(#Null, #Null)
;;;get the ACTUAL BITS of the original hbitmap so we dont destroy it by accident
;setup the first part of the NIF structure
*nif.NIF=AllocateMemory(SizeOf(NIF))
*nif\width=width
*nif\height=height
*nif\sizeuncompressed=sizeimage
Debug sizeimage
Select compression
Case 0 ;BriefLZ
MaxPackedSize.l = BriefLZ_MaxPackedSize(sizeimage)
WorkMemSize.l = BriefLZ_WorkMemSize(sizeimage)
*WorkMem = AllocateMemory(WorkMemSize)
*Destination = AllocateMemory(MaxPackedSize)
lzpackedsize= BriefLZ_Pack(*bitmapdata, *Destination, sizeimage, *WorkMem)
Debug lzpackedsize
*nif\sizecompressed=lzpackedsize
*nif\compression=0
WriteData(0,*nif.NIF,SizeOf(NIF))
WriteData(0,*Destination,lzpackedsize)
CloseFile(0)
Case 1 ;JcalG compression Native to PB
destinationmem=AllocateMemory(sizeimage+8)
packedsize=PackMemory(*bitmapdata,destinationmem,sizeimage,9)
Debug packedsize
*nif\sizecompressed=packedsize
*nif\compression=1
WriteData(0,*nif.NIF,SizeOf(NIF))
WriteData(0,destinationmem,packedsize)
CloseFile(0)
Case 2;ZLIB Compression
SourceLength = sizeimage
DestinationLength = SourceLength + (SourceLength * 0.01) + 12
*DestinationMemoryID = AllocateMemory(DestinationLength)
PureZIP_PackMemory(*bitmapdata, SourceLength, *DestinationMemoryID, @DestinationLength)
*nif\sizecompressed=DestinationLength
Debug DestinationLength
*nif\compression=2
WriteData(0,*nif.NIF,SizeOf(NIF))
WriteData(0,*DestinationMemoryID,DestinationLength)
CloseFile(0)
EndSelect
EndIf
EndProcedure
Procedure LoadNIF(filename.s)
Protected bmpinfo.BITMAPINFO
If ReadFile(0,filename)
*nif.NIF=AllocateMemory(SizeOf(NIF))
ReadData(0,*nif.NIF,SizeOf(NIF))
;create the bitmapinfo structure
With bmpinfo\bmiHeader
\biSize=SizeOf(BITMAPINFOHEADER) ;Size of struct
\biWidth=*nif\width ;Bitmap width
\biHeight= -*nif\height ;Bitmap height, bitmap is top down
\biPlanes=1 ;Single plane
\biBitCount=24 ;Bit depth
\biCompression=#BI_RGB ;No compression
\biSizeImage=0 ;Defaults
\biXPelsPerMeter=0
\biYPelsPerMeter=0
\biClrUsed=0
\biClrImportant=0
EndWith
Debug *nif\width
Debug *nif\height
Debug *nif\sizecompressed
Debug *nif\sizeuncompressed
;read the compressed data
*Source=AllocateMemory(*nif\sizecompressed)
*Destination=AllocateMemory(*nif\sizeuncompressed)
ReadData(0,*Source,*nif\sizecompressed)
; decompress the bitmap bits stored in the file
Select *nif\compression
Case 0 ; briefLZ compressed data
BriefLZ_Depack(*Destination, *Source, *nif\sizeuncompressed)
Case 1 ;JcalG compressed data
Debug UnpackMemory(*Destination, *Source)
Case 2 ; ZLIB compressed data
PureZIP_UnpackMemory(*Source, *nif\sizecompressed, *Destination, *nif\sizeuncompressed)
EndSelect
;Create the bitmap
Protected hdc.l
hdc = CreateDC_("DISPLAY", #Null,#Null, #Null)
hBitmap=CreateDIBitmap_(hdc,bmpinfo\bmiHeader,#CBM_INIT,*Destination,bmpinfo.BITMAPINFO,#DIB_RGB_COLORS)
Debug hBitmap
;set the decompressed bits to the bitmap
;Debug SetDIBits_(hdc, hBitmap, 0,bmpinfo\bmiHeader\biHeight, *Destination, bmpinfo.BITMAPINFO, #DIB_RGB_COLORS)
DeleteDC_(hdc)
FreeMemory(*nif.NIF)
FreeMemory(*Source)
FreeMemory(*Destination)
ProcedureReturn hBitmap
; Else
; DeleteDC_(hdc)
; FreeMemory(*nif.NIF)
; FreeMemory(*Source)
; FreeMemory(*Destination)
; ProcedureReturn #False
; EndIf
Else
ProcedureReturn #False
EndIf
EndProcedure
If OpenWindow(0,0,0,670,620,"Load PCX",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ButtonGadget(0,10,10,80,20,"Open File")
ImageGadget(1,10,50,300,300,0,#PB_Image_Border)
ButtonGadget(2,100,10,80,20,"Save To NIF")
ButtonGadget(3,200,10,80,20,"Open NIF")
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case 0
Pattern.s="BMP Files|*.bmp"
filename.s=OpenFileRequester("Choose An Image File To Open","",Pattern,0)
If filename
hBitmap=LoadImage(0,filename)
SendMessage_(GadgetID(1),#STM_SETIMAGE,#IMAGE_BITMAP,hBitmap)
EndIf
Case 2
hBitmap=SendMessage_(GadgetID(1),#STM_GETIMAGE,#IMAGE_BITMAP,0)
Pattern.s="NIF Files|*.nif"
filename.s=SaveFileRequester("Choose An Image File To Save","",Pattern,0)
If filename
If LCase(GetExtensionPart(filename))<>"nif"
filename+ ".nif"
EndIf
hBitmap=SendMessage_(GadgetID(1),#STM_SETIMAGE,#IMAGE_BITMAP,hBitmap)
SaveNIF(hBitmap,filename,1)
EndIf
Case 3
Pattern.s="NIF Files|*.nif"
filename.s=OpenFileRequester("Choose A NIF File To Open","",Pattern,0)
If filename
hBitmap=LoadNIF(filename)
SendMessage_(GadgetID(1),#STM_SETIMAGE,#IMAGE_BITMAP,hBitmap)
EndIf
EndSelect
Case #PB_Event_CloseWindow
End
EndSelect
ForEver