#UI_ENHANCEMENT
class: PNGReader
class definition
comment/format in:
#paethPredictLeft:above:aboveLeft:
#save:onStream:
changed:
#filterPaeth:
#getIHDRChunk
#setColorType:
tuning
--- a/PNGReader.st Thu Mar 24 05:03:41 2016 +0000
+++ b/PNGReader.st Thu Mar 24 18:31:08 2016 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1996 by Claus Gittinger
All Rights Reserved
@@ -16,9 +14,9 @@
"{ NameSpace: Smalltalk }"
ImageReader subclass:#PNGReader
- instanceVariableNames:'colorType bitsPerChannel depth compressionMethod filterMethod
- interlaceMode bytesPerScanline globalDataChunk thisScanline
- prevScanline'
+ instanceVariableNames:'colorType bitsPerChannel bitsPerPixel depth compressionMethod
+ filterMethod interlaceMode bytesPerScanline globalDataChunk
+ thisScanline prevScanline'
classVariableNames:'Verbose'
poolDictionaries:''
category:'Graphics-Images-Readers'
@@ -482,7 +480,49 @@
|delta|
- delta := self bitsPerPixel // 8 max:1.
+%{
+ if (__isByteArray(__INST(thisScanline))
+ && __isByteArray(__INST(prevScanline))
+ && __isSmallInteger(__INST(depth))
+ && __isSmallInteger(count)) {
+ unsigned char *__thisScanline = __byteArrayVal(__INST(thisScanline));
+ unsigned int __sz_this = __byteArraySize(__INST(thisScanline));
+ unsigned char *__prevScanline = __byteArrayVal(__INST(prevScanline));
+ unsigned int __sz_prev = __byteArraySize(__INST(prevScanline));
+ INT __count = __intVal(count);
+ INT __delta = __intVal(__INST(depth)) / 8;
+ int __i;
+
+ if (__delta < 1) __delta = 1;
+ for (__i=0; __i<__delta; __i++) {
+ unsigned int __pix = __thisScanline[__i] + __prevScanline[__i];
+ __thisScanline[__i] = __pix;
+ }
+ for (; __i < __count; __i++) {
+ int __pCenter = __thisScanline[__i];
+ int __pLeft = __thisScanline[__i - __delta];
+ int __pAbove = __prevScanline[__i];
+ int __pAboveLeft = __prevScanline[__i - __delta];
+ int __pa, __pb, __pc;
+ int __p;
+
+ __pa = (__pAbove - __pAboveLeft);
+ __pa = __pa < 0 ? -__pa : __pa;
+ __pb = (__pLeft - __pAboveLeft);
+ __pb = __pb < 0 ? -__pb : __pb;
+ __pc = __pLeft + __pAbove - __pAboveLeft - __pAboveLeft;
+ __pc = __pc < 0 ? -__pc : __pc;
+ if ((__pa <= __pb) && (__pa <= __pc)) __p = __pLeft;
+ else if (__pb <= __pc) __p = __pAbove;
+ else __p = __pAboveLeft;
+
+ __thisScanline[__i] = __pCenter + __p;
+ }
+ RETURN(self);
+ }
+%}.
+
+ delta := depth // 8 max:1.
1 to:delta do:[:i |
thisScanline
at:i
@@ -521,20 +561,20 @@
"Modified: / 03-05-2011 / 12:14:34 / cg"
!
-paethPredictLeft: a above: b aboveLeft: c
+paethPredictLeft: l above: a aboveLeft: al
"Predicts the value of a pixel based on nearby pixels, based on Paeth (GG II, 1991)"
| pa pb pc |
- pa := b > c ifTrue: [b - c] ifFalse: [c - b].
- pb := a > c ifTrue: [a - c] ifFalse: [c - a].
- pc := a + b - c - c.
+ pa := a > al ifTrue: [a - al] ifFalse: [al - a].
+ pb := l > al ifTrue: [l - al] ifFalse: [al - l].
+ pc := l + a - al - al.
pc < 0 ifTrue: [
pc := pc * -1
].
- ((pa <= pb) and: [pa <= pc]) ifTrue: [^ a].
- (pb <= pc) ifTrue: [^ b].
- ^ c
+ ((pa <= pb) and: [pa <= pc]) ifTrue: [^ l].
+ (pb <= pc) ifTrue: [^ a].
+ ^ al
! !
!PNGReader methodsFor:'private-pixel copy'!
@@ -761,7 +801,8 @@
].
self reportDimension.
- depth := inStream nextByte. "/ bits-per-channel
+ bitsPerChannel := inStream nextByte.
+ depth := bitsPerChannel. "/ will be changed by setColorType.
colorType := inStream nextByte.
compressionMethod := inStream nextByte.
@@ -772,7 +813,7 @@
'PNGReader: IHDR:' infoPrintCR.
'PNGReader: width: ' infoPrint. width infoPrintCR.
'PNGReader: height: ' infoPrint. height infoPrintCR.
- 'PNGReader: depth: ' infoPrint. depth infoPrintCR.
+ 'PNGReader: bitsPerChannel: ' infoPrint. bitsPerChannel infoPrintCR.
'PNGReader: colorType: ' infoPrint. colorType infoPrintCR.
'PNGReader: compressionMethod: ' infoPrint. compressionMethod infoPrintCR.
'PNGReader: filterMethod: ' infoPrint. filterMethod infoPrintCR.
@@ -789,51 +830,56 @@
colorType == 0 ifTrue:[
photometric := #blackIs0.
samplesPerPixel := 1.
- bitsPerSample := Array with:depth.
+ bitsPerSample := Array with:bitsPerChannel.
+ depth := bitsPerChannel.
^ true.
].
colorType == 2 ifTrue:[
- depth < 8 ifTrue:[
+ bitsPerChannel < 8 ifTrue:[
'PNGReader: invalid colorType/depth combination' infoPrintCR.
^ false.
].
photometric := #rgb.
samplesPerPixel := 3.
- bitsPerSample := Array with:depth with:depth with:depth.
+ bitsPerSample := Array with:bitsPerChannel with:bitsPerChannel with:bitsPerChannel.
+ depth := bitsPerChannel * 3.
^ true.
].
colorType == 3 ifTrue:[
- depth == 16 ifTrue:[
+ bitsPerChannel == 16 ifTrue:[
'PNGReader: invalid colorType/depth combination' infoPrintCR.
^ false.
].
photometric := #palette.
samplesPerPixel := 1.
- bitsPerSample := Array with:depth.
+ bitsPerSample := Array with:bitsPerChannel.
+ depth := bitsPerChannel.
^ true.
].
colorType == 4 ifTrue:[
- depth < 8 ifTrue:[
+ bitsPerChannel < 8 ifTrue:[
'PNGReader: invalid colorType/depth combination' infoPrintCR.
^ false.
].
photometric := #blackIs0.
samplesPerPixel := 2.
- bitsPerSample := Array with:depth with:depth.
+ bitsPerSample := Array with:bitsPerChannel with:bitsPerChannel.
+ depth := bitsPerChannel * 2.
^ true.
].
colorType == 6 ifTrue:[
- depth < 8 ifTrue:[
+ bitsPerChannel < 8 ifTrue:[
'PNGReader: invalid colorType/depth combination' infoPrintCR.
^ false.
].
photometric := #rgb.
samplesPerPixel := 4.
- bitsPerSample := Array with:depth with:depth with:depth with:depth.
+ bitsPerSample := Array with:bitsPerChannel with:bitsPerChannel with:bitsPerChannel with:bitsPerChannel.
+ depth := bitsPerChannel * 4.
^ true.
].