Commit 30964e0b authored by Robert Sprowson's avatar Robert Sprowson

Add PNG reading ability

Also increased the minimum work area of the uutput window so the up/down adjusters don't get squashed with very small images.

Tested with 174 test PNGs from the PNG test suite.

Version 1.43. Tagged as 'ChangeFSI-1_43'
parent 59019698
......@@ -63,6 +63,8 @@ Alpiar 36 bit per pixel
Alpiar 48 bit per pixel
Kodak RGB images, 24 bits per pixel
BTPC 4.1 images
Portable network graphics 1, 2, 4, 8, 16, 24, 48 bits per pixel
interlaced or non interlaced image ordering
Output formats
--------------
......@@ -666,6 +668,19 @@ BTPC 4.1 images
Binary tree predictive coding is used to achieve a signal to noise ratio
better than that achieved with a JPEG algorithm, and in less time too.
Portable network graphics
-------------------------
Recognised by unique 8 byte signature at the start of the file.
The reader is based on the PNG 1.2 specification, and supports all of
the critical chunks described in the specification. All defined filter types
and interlacing schemes are also supported.
The ancilliary chunks, such as gamma correction and histogram, are ignored
as on the whole ChangeFSI already has a means to manipulate these parameters.
Some chunks are for information only (such as the various supplementary text
and date stamp information).
Table summarising the formats
=============================
......@@ -720,3 +735,4 @@ Alpiar 36 bit per pixel [ALPIAR12 at start of file]
Alpiar 48 bit per pixel [ALPIAR16 at start of file]
Kodak RGB images, 24 bits per pixel [named /RGB]
BTPC file [bptc at start of file]
Portable network graphics [8 byte signature at start of file]
......@@ -530,7 +530,7 @@ Adding a new format is a matter of:
Reading the size of the image and the colour palette mapping in the next
section of the program.
Writing a "read pixel row" element inside PROCiprow.
Writing a "read pixel row" FN named in r$ and called from PROCreadpixelrow.
Providing an entry in PROCrewind.
......
......@@ -41,7 +41,6 @@ LDIR = ${LOCALE}
SDIR = source
CFSIDIR = ${INSTDIR}.${APP}
VPATH = @ JPEG6b hpcdtoppm btpc
MSGVERSION = ${AWK} -f Build:AwkVers
MSGS = ${DDIR}.Messages
include StdTools
......@@ -90,6 +89,7 @@ FILES =\
${DDIR}.djpeg.HourOff\
${DDIR}.djpeg.!Run\
${DDIR}.ChangeFSI\
${DDIR}.CFSIpng\
${DDIR}.cjpeg \
${DDIR}.JPEGprint.!Run \
${DDIR}.JPEGprint.JPEGprint
......@@ -200,7 +200,7 @@ all: ${FILES}
@${ECHO} ${COMPONENT}: all built
#
# Note that CFSIjpeg {required} comes as a byproduct of the SprExtend component
# Note that CFSIjpeg (required) comes as a byproduct of the SprExtend component
#
install: ${FILES}
Set Alias$CPFD ${CP} %0.%1 ${CFSIDIR}.%1 ${CPFLAGS}
......@@ -241,6 +241,7 @@ install: ${FILES}
CPFDL ${LDIR} Templates
CPFDL ${LDIR} Template3D
CPFDL ${DDIR} ChangeFSI
CPFDL ${DDIR} CFSIpng
CPFDL ${DDIR} cjpeg
${MKDIR} ${CFSIDIR}.btpc
CPFDL ${DDIR} btpc.btpc
......@@ -262,15 +263,14 @@ install: ${FILES}
@${ECHO} ${COMPONENT}: installed
clean:
${RM} ${DDIR}.ChangeFSI
${RM} ${DDIR}.JPEGprint.JPEGprint
${RM} ${DDIR}.btpc.btpc
${RM} ${DDIR}.DJpeg.DJpeg
${RM} ${DDIR}.CJpeg
${RM} CJpeg
${RM} DJpeg
${RM} ${DDIR}.hpcdtoppm
${RM} ${MSGS}
${RM} ${DDIR}.ChangeFSI
${RM} ${DDIR}.CFSIpng
${RM} ${DDIR}.cjpeg
${RM} ${DDIR}.btpc.btpc
${RM} ${DDIR}.djpeg.djpeg
${RM} ${DDIR}.JPEGprint.JPEGprint
${XWIPE} n ${WFLAGS}
${XWIPE} o.* ${WFLAGS}
@${ECHO} ${COMPONENT}: cleaned
......@@ -317,10 +317,17 @@ ${DDIR}.btpc.btpc: ${BOBJS} ${C++LIB} ${CLIB}
${LD} -c++ -o $@ ${BOBJS} ${C++LIB} ${CLIB}
${SQZ} $@
#------------------------------------------------------------------------------
# CFSIPNG
#------------------------------------------------------------------------------
${DDIR}.CFSIPNG: ${SDIR}.CFSI-PNG
${AS} ${ASFLAGS} -o CFSIpng.o ${SDIR}.CFSI-PNG
${LD} -bin -o $@ CFSIpng.o
#------------------------------------------------------------------------------
# MESSAGES
#------------------------------------------------------------------------------
${MSGS}: ${LDIR}.Messages VersionNum
${MSGVERSION} ${LDIR}.Messages > $@
${INSERTVERSION} ${LDIR}.Messages > $@
# Dynamic dependencies:
No preview for this file type
No preview for this file type
/* (1.42)
/* (1.43)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 1.42
#define Module_MajorVersion_CMHG 1.43
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 08 Jan 2014
#define Module_MajorVersion "1.42"
#define Module_Version 142
#define Module_MajorVersion "1.43"
#define Module_Version 143
#define Module_MinorVersion ""
#define Module_Date "08 Jan 2014"
......@@ -18,6 +18,6 @@
#define Module_ComponentName "ChangeFSI"
#define Module_ComponentPath "mixed/RiscOS/Sources/Apps/ChangeFSI"
#define Module_FullVersion "1.42"
#define Module_HelpVersion "1.42 (08 Jan 2014)"
#define Module_LibraryVersionInfo "1:42"
#define Module_FullVersion "1.43"
#define Module_HelpVersion "1.43 (08 Jan 2014)"
#define Module_LibraryVersionInfo "1:43"
This diff is collapsed.
......@@ -1788,6 +1788,7 @@ DEF FNChangeFSI(A$,spritearea%,workspace%,worklimit%,oksave%,okinfo%,RETURN ram%
IF flag=-1 IF LEFT$(S$,4)="FORM" IF MID$(S$,9,4)="ILBM" flag=1600
IF flag=-1 IF LEFT$(S$,8)="ALPIAR12" flag=3900:colourindex=4095
IF flag=-1 IF LEFT$(S$,8)="ALPIAR16" flag=3905:colourindex=65535
IF flag=-1 IF LEFT$(S$,8)=CHR$&89+"PNG"+CHR$13+CHR$10+CHR$26+CHR$10 flag=4000
IF flag=-1 THEN
IF MID$(S$,7,4)="JFIF" OR LEFT$(S$,3)=CHR$&FF+CHR$&D8+CHR$&FF OR ftype=&C85 THEN
REM Read the cache size variable
......@@ -4059,6 +4060,124 @@ DEF FNChangeFSI(A$,spritearea%,workspace%,worklimit%,oksave%,okinfo%,RETURN ram%
gbo%=2
bbo%=4
info$="Ronald Alpiar format, "+ STR$sx%+" by "+ STR$sy%+" pixels, 48 bits per pixel"
WHEN 4000
REM Portable network graphics (PNG)
PTR#c%=8
A%=OPENIN"<ChangeFSI$Dir>.CFSIpng"
IF A%=0 THEN ERROR 42,"Can't load PNG support code"
png%=FNdim(EXT#A%)
SYS 12,4,A%,png%,EXT#A%
CLOSE#A%
SYS "XOS_CLI","rmensure ZLib 0 rmload System:Modules.ZLib"
OSCLI"rmensure ZLib 0 ERROR ChangeFSI requires the ZLib module to perform this operation"
png1st%=0:REM File PTR of 1st IDAT
T%=0:REM Tag order checking has seen nothing
V%=TRUE:REM Validity starts OK
REPEAT
L%=FNbeW:t$=CHR$BGET#c%+CHR$BGET#c%+CHR$BGET#c%+CHR$BGET#c%
CASE t$ OF
WHEN"IHDR"
IF T%<>0 THEN V%=FALSE ELSE T%=T% OR1:REM Only once, must come first
sx%=FNbeW
sy%=FNbeW
PNGdep%=BGET#c%:REM Bit depth
PNGcol%=BGET#c%:REM Type 0 is greyscale 1/2/4/8/16bpp
REM Type 2 is 24/48bpp RGB
REM Type 3 is paletted 1,2,4,8bpp
REM Type 4 is 8/16bpp greyscale + alpha
REM Type 6 is 24/48bpp RGB + alpha
PNGcmp%=BGET#c%:PNGflt%=BGET#c%:PNGint%=BGET#c%:REM Compressor, filter, interlacing
C%=FNbeW:REM Skip CRC32
WHEN"PLTE"
IF (T% AND15)<>1 THEN V%=FALSE ELSE T%=T% OR2:REM Only once, before IDAT, before IEND
IF (L% MOD3)<>0 THEN ERROR42, "PNG palette must have R/G/B triplets"
L%=L% DIV3
FOR C%=0 TO L%-1
r%(C%)=BGET#c%/255*F
g%(C%)=BGET#c%/255*F
b%(C%)=BGET#c%/255*F
NEXT
C%=FNbeW:REM Skip CRC32
WHEN"IDAT"
IF (T% AND9)<>1 THEN V%=FALSE ELSE T%=T% OR4:REM Can be multiple, after IHDR, before IEND, PLTE optional
IF png1st%=0 AND L%<>0 THEN png1st%=PTR#c%-8:REM Latch first occupied IDAT for rewind
PTR#c%=PTR#c%+L%+4:REM Skip data & CRC32
WHEN"IEND"
IF (T% AND13)<>5 THEN V%=FALSE ELSE T%=T% OR8:REM Only once, must be last, PLTE optional
IF L%<>0 THEN ERROR42, "IEND contains data"
C%=FNbeW:REM Skip CRC32
OTHERWISE
PTR#c%=PTR#c%+L%+4:REM Skip unhandled tags
ENDCASE
UNTIL EOF#c%
IF NOT V% THEN ERROR42,"Out of order tag in PNG"
CASE PNGcol% OF
WHEN0: IF PNGdep%<>1 AND PNGdep%<>2 AND PNGdep%<>4 AND PNGdep%<>8 AND PNGdep%<>16 THEN V%=FALSE
WHEN2,4,6: IF PNGdep%<>8 AND PNGdep%<>16 THEN V%=FALSE
WHEN3: IF PNGdep%<>1 AND PNGdep%<>2 AND PNGdep%<>4 AND PNGdep%<>8 THEN V%=FALSE
OTHERWISE: V%=FALSE
ENDCASE
IF NOT V% THEN ERROR42,"Invalid PNG colour combination"
IF ((PNGcol%=0 OR PNGcol%=4) AND (T% AND2)=2) THEN ERROR42,"Unexpected palette with greyscale PNG"
IF (PNGcol%=3 AND (T% AND2)=0) THEN ERROR42,"Expected palette for colour indexed PNG"
IF PNGcmp%<>0 OR PNGflt%<>0 THEN ERROR42,"Unsupported compressor or filter type for PNG"
IF PNGint%<>0 AND PNGint%<>1 THEN ERROR42,"Unsupported interlacing scheme for PNG"
CASE PNGcol% OF
WHEN 0: quant%=PNGdep%:input=quant%+(8*(PNGdep%=16))
bppbytes%=(PNGdep%+7) DIV8:bppbits%=quant%
r$="FN4008":PROCflatpal(1<<input)
WHEN 2: quant%=3*PNGdep%:input=quant%
bppbytes%=3*(PNGdep% DIV8):bppbits%=quant%
r$="FN4024":PROCnopal:rbo%=0:gbo%=1*(PNGdep% DIV8):bbo%=2*(PNGdep% DIV8)
WHEN 3: quant%=PNGdep%:input=quant%
bppbytes%=1:bppbits%=quant%
r$="FN4008":REM Palette from PLTE tag
WHEN 4: quant%=PNGdep%:input=8
bppbytes%=2*(PNGdep% DIV8):bppbits%=2*PNGdep%
r$="FN4008":PROCflatpal(256)
WHEN 6: quant%=3*PNGdep%:input=quant%
bppbytes%=4*(PNGdep% DIV8):bppbits%=4*PNGdep%
r$="FN4024":PROCnopal:rbo%=0:gbo%=1*(PNGdep% DIV8):bbo%=2*(PNGdep% DIV8)
ENDCASE
IF PNGint%=1 THEN
s$="Interlaced"
pngsub%=7:DIM st%(7)
FOR S%=1 TO 7:REM For each subimage, calculate pixels per row
CASE S% OF
WHEN 1: st%(S%)=(sx%+7) DIV8
WHEN 2: st%(S%)=(sx%+3) DIV8
WHEN 3: st%(S%)=(sx%+3) DIV4:IF sy%<5 THEN st%(S%)=0:REM Empty
WHEN 4: st%(S%)=(sx%+1) DIV4
WHEN 5: st%(S%)=(sx%+1) DIV2:IF sy%<3 THEN st%(S%)=0:REM Empty
WHEN 6: st%(S%)=(sx%+0) DIV2
WHEN 7: st%(S%)=(sx%+0) DIV1:IF sy%<2 THEN st%(S%)=0:REM Empty
ENDCASE
NEXT
ELSE
s$="Progressive"
pngsub%=1:DIM st%(1)
st%(1)=sx%
pngbuff%=0
ENDIF
FOR S%=1 TO pngsub%:REM For each subimage, calculate whole bytes per row
CASE PNGcol% OF
WHEN 0,3: st%(S%)=((st%(S%)*PNGdep%)+7) DIV8
WHEN 2,4,6: st%(S%)=st%(S%)*bppbytes%
ENDCASE
NEXT
PROCcachesize
datacache%=FNcachedim(cache%)
IF datacache%=-1 datacache%=FNdim(cache%)
pngspace%=cache% DIV pngsub%:REM Divide up the data cache equally by subimage
cache%=FALSE:REM Lines are compressed and interleaved with pesky IDATs, don't use built in refiller
buff%=FNdim(2*(SUM(st%())+pngsub%)):REM Current/previous rows, plus 1 extra for the filter type
IF PNGint%=1 THEN pngbuff%=FNdim(st%(7)+7):REM Extra row for deinterlacing, plus MAX(32,48,56) bit overshoot
A%=0:A%=USR (png%+0):pngblk%=FNdim(A%*pngsub%):REM Decompress state per subimage
PROCrewind
step24=bppbytes%
bigendianbits=TRUE
IF (PNGcol%=0 OR PNGcol%=4) THEN s$+=" greyscale" ELSE s$+=" colour"
info$=s$+" PNG, "+ STR$sx%+" by "+ STR$sy%+" pixels, "+FNbits(quant%)
ENDCASE
IF info% PRINT info$
SYS "Hourglass_On"
......@@ -10316,6 +10435,30 @@ DEF FN3724(z%())
= TRUE
:
REM
DEF FN4008(z%())
A%=pngblk%
B%=c%
C%=pngy%:pngy%+=1
D%=sy%
E%=pngbuff%
rb%=USR (png%+4):REM Decompress a line of 8bpp-equivalent
CALL mappix%,z%(1,0),r%(0),g%(0),b%(0),rb%
= TRUE
:
REM
DEF FN4024(z%())
A%=pngblk%
B%=c%
C%=pngy%:pngy%+=1
D%=sy%
E%=pngbuff%
rb%=USR (png%+4):REM Decompress a line of 24bpp-equivalent
gb%=rb%+gbo%
bb%=rb%+bbo%
CALL mappix%,z%(1,0),r%(0),g%(0),b%(0),rb%,gb%,bb%
= TRUE
:
REM
DEF PROCrewind
rows%=sy%
CASE flag OF
......@@ -10448,6 +10591,16 @@ DEF PROCrewind
jpegy%=sy%
WHEN 3900,3905
PTR#c%=st%
WHEN 4000
pngy%=0
A%=pngblk%
B%=buff%
C%=datacache%
D%=pngspace%
E%=png1st%
F%=bppbytes%+(bppbits%<<8)
G%=pngsub%
CALL (png%+0),st%(0):REM Prime the helper
ENDCASE
IF cache% THEN
IF flag=3600 THEN
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment