This doesn't guarantee that a PNG file is 100% valid, but it gives a few sanity checks before attempting to save and process the file as PNG.
Makes sure that there's a valid PNG header and checks the dimensions to make sure they're in range of your specifications.
This way, the image never needs to hit the disk if it doesn't pass the vetting.
Usage:
MyImageST StringTheory
MyMessageST StringTheory
CODE
!Assuming MyImageST already contains the PNG data
IF NOT ValidatePNGFile(MyImageST,MyMessageST)
!Don't bother saving/processing
MESSAGE('Invalid Image: ' & MyMessageST.GetValue())
END
ValidatePNGFile PROCEDURE (StringTheory pPngContentsST,StringTheory pResultMsgST,|
LONG pMinWidth=10,LONG pMaxWidth=1200,LONG pMinHeight=10,LONG pMaxHeight=1200)!,LONG
S STRING(4) !4 bytes to be examined as LONG using L.
L LONG,OVER(S)
IHDRPos LONG !Position of the IHDR chunk
ST StringTheory !Utility StringTheory object.
CODE
LOOP 1 TIMES
pResultMsgST.SetValue('')
IF pPngContentsST.Slice(1,8) <> '<089h,050h,04Eh,047h,00Dh,00Ah,01Ah,00Ah>'
pResultMsgST.SetValue('Invalid PNG file')
BREAK
END
IHDRPos = pPngContentsST.Instring('IHDR')
IF NOT IHDRPos
pResultMsgST.SetValue('Cannot Determine PNG Dimensions')
BREAK
END
S = pPngContentsST.Slice(IHDRPos + 4,IHDRPos + 8 ) !Getting The Width (but it's BigEndian)
L = ST.SwitchEndian(L) !Switch to LittleEndian so we can read it.
IF L < pMinWidth OR L > pMaxWidth
pResultMsgST.SetValue('Width is out of Bounds: Value=' & L & ' Minimum=' & pMinWidth & ' Maximum=' & pMaxWidth)
BREAK
END
S = pPngContentsST.Slice(IHDRPos + 8,IHDRPos + 12) !Getting The Height (but it's BigEndian)
L = ST.SwitchEndian(L) !Switch to LittleEndian so we can read it.
IF L < pMinHeight OR L > pMaxHeight
pResultMsgST.SetValue('Height is out of Bounds: Value=' & L & ' Minimum=' & pMinHeight & ' Maximum=' & pMaxHeight)
BREAK
END
RETURN 1
END
RETURN 0