|
Class: PNGReader
Object
|
+--ImageReader
|
+--PNGReader
- Package:
- stx:libview2
- Category:
- Graphics-Images-Readers
- Version:
- rev:
1.111
date: 2023/11/24 09:04:21
- user: matilk
- file: PNGReader.st directory: libview2
- module: stx stc-classLibrary: libview2
This class provides methods for loading and saving PNG pictures.
It is currenty unfinished (some interlaced image formats are unsupported, for example: grayscale+alpha)
In the meantime, use a pngtoXXX converter for interlaced images, and read XXX.
[caveats:]
writer can only store mask with depth24 images (for now).
writer only generates unfiltered non-interlaced data.
[Special:]
the EnforcedImageTypeQuery is asked for;
if #rgb is returned AND the image is rgba, then the alpha channel is ignored
and an rgb (Depth24Image) is returned instead.
Proprietary chunks can be extracted by defining a specialChunkHandler,
which is invoked (indexed by chunkType) with the chunk data when such a
chunk is encountered. This allows for private data to be extracted.
(labview does this, and expecco can do this)
Proprietary chunks can be written by setting the specialChunks collection
before writing.
copyrightCOPYRIGHT (c) 1996 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
accessing
-
pngHeader
-
class initialization
-
initialize
-
install myself in the Image classes fileFormat table for the `.png' extension.
queries
-
canRepresent: anImage
-
return true, if anImage can be represented in my file format.
Any image without mask is supported;
only depth24 images with mask are (currently).
testing
-
file: filename hasSpecialChunk: chunkTag
-
true if there is a special chunk with chunkTag in filename
-
hasValidImageHeader: someHeaderBytes
-
return true, if someHeaderBytes
(which does not need to be the whole data, but large enough
to detect the header) contains a valid TIFF image header
-
isValidImageStream: inStream
-
return true, if inStream contains a PNG image.
Does not really validate - just looks at the header bytes
accessing
-
extractSpecialChunksOnly: aBoolean
-
if set to true, only special chunks will be processed via
corresponding specialChunkHandlers.
No image will be extracted.
The default is (of course) false.
-
makeImage
-
(comment from inherited method)
return the image as represented by the values found in my
instvars; these have been typically set as a side effect of
the fromStream:-method, which reads images.
-
specialChunks: aDictionaryOfChunkTypesAndBlobs
-
Modified (format): / 27-10-2018 / 16:09:56 / Claus Gittinger
hooks
-
specialChunkHandlerAt: chunkType put: aHandlerBlock
-
define a handler action, which processes unknown chunks.
The handler block will be called with one or two arguments:
the binary data of the chunk, and optionally the reader itself
reading
-
fromStream: aStream
-
read a stream containing a PNG image.
Leave the image description in instance variables
(i.e. to get the image, ask with #image).
reading-private
-
generateMaskFromPaletteAlphaEntries
-
if there is only one entry to care for...
-
getChunk
-
Verbose := true.
-
getIHDRChunk
-
for now - might be changed by setColorType.
-
handleText: text keyword: keyword
-
things like exif data etc.
-
setColorType: colorType
-
0
reading-private chunks
-
doPass: passNr
-
Certain interlace passes are skipped with certain small image dimensions;
Return true, if that pass is to be performed
-
processACTLChunkLen: len
-
APNG animation control
-
processBKGDChunkLen: len
-
background color chunk
-
processCHRMChunkLen: len
-
cHRM Primary chromaticities chunk - currently unhandled
-
processChunk: type len: len
-
---since the compressed data can span multiple
chunks, stitch them all together first. later,
if memory is an issue, we need to figure out how
to do this on the fly---
-
processDSIGChunkLen: len
-
digital signature; see
-
processEXEXChunkLen: len
-
this chunk contains an expecco sample network.
-
processEXIFChunkLen: len
-
Exchangeable Image File (Exif) Profile chunk.
-
processFCTLChunkLen: len
-
APNG frame control
-
processFDATChunkLen: len
-
APNG frame data
-
processGAMAChunkLen: len
-
currently ignored
-
processGlobalIDATChunk
-
-
processHISTChunkLen: len
-
currently ignored
-
processICCPChunkLen: len
-
currently ignored
-
processIDATChunkLen: len
-
-
processIHDRChunkLen: len
-
image header chunk
-
processITXTChunkLen: len
-
international (i.e.utf8) textual data.
-
processInterlacedDATA: len
-
-
processInterlacedGlobalDATA
-
adam7 interlace method
-
processNIVIChunkLen: len
-
this chunk contains a labView vi.
-
processNonInterlacedDATA: len
-
-
processNonInterlacedGlobalDATA
-
data n
-
processPHYSChunkLen: len
-
physical pixel chunk - currently unhandled
-
processPLTEChunkLen: len
-
read a color palette
-
processSBITChunkLen: len
-
currently ignored
-
processSPALChunkLen: len
-
currently ignored
-
processSRGBChunkLen: len
-
currently ignored
-
processTEXTChunkLen: len
-
textual data in iso8859 coding.
-
processTIMEChunkLen: len
-
currently ignored - not needed to display png images
-
processTRNSChunkLen: len
-
Modified (format): / 23-06-2020 / 17:46:15 / Stefan Vogel
-
processZTXTChunkLen: len
-
compressed text
reading-private filtering
-
filterAverage: count
-
Use the average of the pixel to the left and the pixel above as a predictor
-
filterHorizontal: count
-
use the pixel to the left as a predictor
-
filterNone: count
-
no filter - scanline is as is
-
filterPaeth: count
-
Select one of (the pixel to the left, the pixel above and the pixel to above left) to
predict the value of this pixel
-
filterScanline: filterType count: count
-
-
filterVertical: count
-
Use the pixel above as a predictor
-
paethPredictLeft: l above: a aboveLeft: al
-
Predicts the value of a pixel based on nearby pixels, based on Paeth (GG II, 1991)
reading-private pixel copy
-
copyPixels: y at: startX by: incX
-
Handle interlaced pixels of supported colorTypes
-
copyPixelsGray: y at: startX by: incX
-
Handle interlaced pixels of supported colorTypes.
-
copyPixelsGrayAlpha: y at: startX by: incX
-
Handle interlaced pixels of supported colorTypes.
-
copyPixelsIndexed: y at: startX by: incX
-
-
copyPixelsRGB: y at: startX by: incX
-
Handle interlaced pixels of supported colorTypes.
-
copyPixelsRGBA: y at: startX by: incX
-
Handle interlaced pixels of supported colorTypes.
writing
-
save: imageArg onStream: aStream
-
save image in PNG-file-format onto aStream
writing-private
-
determinePaletteIndexForMaskedPixels
-
Assume a new color entry for the masked pixels and assign these pixels to it.
writing-private chunks
-
determineColorTypeAndHasMask
-
sets colorType as side effect;
returns boolean if a mask is present
-
writeChunk: chunkTypeChars size: len with: aBlock
-
-
writeEndChunk
-
-
writeIHDRChunk
-
make it grayAlpha / rgbAlpha
-
writeImageDataChunk
-
for now - only support depth24 + mask
-
writePaletteChunk
-
if there is an index for the masked pixels at the end of the color map
-
writeSpecialChunks
-
-
writeTRNSChunk
-
for all remaining palette entries without a set value, it is assumed to be 255
PNGReader save:(ToolbarIconLibrary systemBrowserIcon) onFile:'/tmp/icon.png'.
ImageEditor openOnFile:'/tmp/icon.png'
|
|img img2 outStream png|
img := ToolbarIconLibrary error32x32Icon.
outStream := WriteStream on:(ByteArray new:100).
PNGReader save:img onStream:outStream.
png := outStream contents.
img2 := PNGReader fromStream:(png readStream).
self assert:(img bits = img2 bits).
img inspect.
img2 inspect.
|
Sorry, that doesn't work yet:
|outStream|
outStream := '' readWriteStream.
PNGReader save:(ToolbarIconLibrary systemBrowserIcon) onStream:(Base64Coder on:outStream).
outStream
|