PNGReader.st
changeset 3762 036884e46f66
parent 3724 4a753c4710c9
child 3797 e17e95f379eb
child 3819 6cc53953e65c
equal deleted inserted replaced
3760:3ce893a0629d 3762:036884e46f66
     1 "{ Encoding: utf8 }"
       
     2 
       
     3 "
     1 "
     4  COPYRIGHT (c) 1996 by Claus Gittinger
     2  COPYRIGHT (c) 1996 by Claus Gittinger
     5               All Rights Reserved
     3               All Rights Reserved
     6 
     4 
     7  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
    16 "{ NameSpace: Smalltalk }"
    14 "{ NameSpace: Smalltalk }"
    17 
    15 
    18 ImageReader subclass:#PNGReader
    16 ImageReader subclass:#PNGReader
    19 	instanceVariableNames:'colorType bitsPerChannel depth compressionMethod filterMethod
    17 	instanceVariableNames:'colorType bitsPerChannel depth compressionMethod filterMethod
    20 		interlaceMode bytesPerScanline globalDataChunk thisScanline
    18 		interlaceMode bytesPerScanline globalDataChunk thisScanline
    21 		prevScanline'
    19 		prevScanline processTextChunks'
    22 	classVariableNames:'Verbose'
    20 	classVariableNames:'Verbose'
    23 	poolDictionaries:''
    21 	poolDictionaries:''
    24 	category:'Graphics-Images-Readers'
    22 	category:'Graphics-Images-Readers'
    25 !
    23 !
    26 
    24 
   213     type = 'pHYs' ifTrue:[^ self processPHYSChunkLen:len].
   211     type = 'pHYs' ifTrue:[^ self processPHYSChunkLen:len].
   214     type = 'cHRM' ifTrue:[^ self processCHRMChunkLen:len].
   212     type = 'cHRM' ifTrue:[^ self processCHRMChunkLen:len].
   215     type = 'tRNS' ifTrue:[^ self processTRNSChunkLen:len].
   213     type = 'tRNS' ifTrue:[^ self processTRNSChunkLen:len].
   216     type = 'IHDR' ifTrue:[^ self processIHDRChunkLen:len].
   214     type = 'IHDR' ifTrue:[^ self processIHDRChunkLen:len].
   217 
   215 
       
   216     type = 'iTXt' ifTrue:[^ self processITXTChunkLen:len].
       
   217     type = 'iCCP' ifTrue:[^ self processICCPChunkLen:len].
       
   218     
   218     ('PNGReader: unrecognized chunk: ' , type , ' ignored.') infoPrintCR.
   219     ('PNGReader: unrecognized chunk: ' , type , ' ignored.') infoPrintCR.
   219 
   220 
   220     inStream skip:len.
   221     inStream skip:len.
   221     ^ true.
   222     ^ true.
   222 
   223 
   236         ^ self processNonInterlacedGlobalDATA
   237         ^ self processNonInterlacedGlobalDATA
   237     ]. 
   238     ]. 
   238     ^ self processInterlacedGlobalDATA
   239     ^ self processInterlacedGlobalDATA
   239 !
   240 !
   240 
   241 
       
   242 processICCPChunkLen:len
       
   243     "/ ignored
       
   244     "/ inStream nextBytes:len.
       
   245 
       
   246     inStream skip:len.
       
   247     ^ true
       
   248 
       
   249     "Created: 21.6.1996 / 21:15:58 / cg"
       
   250 !
       
   251 
   241 processIDATChunkLen:len
   252 processIDATChunkLen:len
   242     interlaceMode == 0 ifTrue: [
   253     interlaceMode == 0 ifTrue: [
   243         ^ self processNonInterlacedDATA:len
   254         ^ self processNonInterlacedDATA:len
   244     ]. 
   255     ]. 
   245     ^ self processInterlacedDATA:len
   256     ^ self processInterlacedDATA:len
       
   257 !
       
   258 
       
   259 processIHDRChunkLen:len
       
   260     "/ ignored
       
   261     
       
   262     inStream skip:len.
       
   263     ^ true
       
   264 
       
   265     "Created: 21.6.1996 / 21:15:58 / cg"
       
   266 !
       
   267 
       
   268 processITXTChunkLen:len
       
   269     "/ international (i.e.utf8) textual data.
       
   270     
       
   271     "/ currently ignored - not needed to display png images
       
   272     "/
       
   273     "/   Keyword:             1-79 bytes (character string)
       
   274     "/   Null separator:      1 byte
       
   275     "/   Compression flag:    1 byte
       
   276     "/   Compression method:  1 byte
       
   277     "/   Language tag:        0 or more bytes (character string)
       
   278     "/   Null separator:      1 byte
       
   279     "/   Translated keyword:  0 or more bytes
       
   280     "/   Null separator:      1 byte
       
   281     "/   Text:                0 or more bytes
       
   282 
       
   283     "/ if needed, set processTextChunks to true somewhere...
       
   284     processTextChunks == true ifTrue:[
       
   285         |chunkData keyword text i1 i2 i3 
       
   286          compressionFlag compressionMethod languageTag
       
   287          xlatedKeyword textBytes|
       
   288 
       
   289         chunkData := inStream nextBytes:len.
       
   290         i1 := chunkData indexOf:0.
       
   291         keyword := (chunkData copyTo:i1-1) asString.
       
   292         compressionFlag := chunkData at:i1+1.
       
   293         compressionMethod := chunkData at:i1+2.
       
   294         i2 := chunkData indexOf:0 startingAt:i1+3.
       
   295         languageTag := (chunkData copyFrom:i1+3 to:i2-1) asString.
       
   296         i3 := chunkData indexOf:0 startingAt:i2+1.
       
   297         xlatedKeyword := (chunkData copyFrom:i2+1 to:i3-1) asString.
       
   298         textBytes := chunkData copyFrom:i3+1.
       
   299         compressionFlag == 0 ifTrue:[
       
   300             text := textBytes
       
   301         ] ifFalse:[
       
   302             compressionFlag == 1 ifTrue:[
       
   303                 "/ for now, only zlib compression is supported...
       
   304                 'zlib compression currently unsupported' infoPrintCR.
       
   305             ] ifFalse:[
       
   306                 'unsupported compression method' infoPrintCR.
       
   307             ].    
       
   308         ].    
       
   309         text := text utf8Decoded.
       
   310         self handleText:text keyword:keyword.
       
   311     ] ifFalse:[    
       
   312         inStream skip:len.
       
   313     ].
       
   314     ^ true
       
   315 
       
   316     "Created: 21.6.1996 / 21:15:58 / cg"
   246 !
   317 !
   247 
   318 
   248 processInterlacedDATA:len
   319 processInterlacedDATA:len
   249     inStream skip:len.
   320     inStream skip:len.
   250     ^ true
   321     ^ true
   423     ^ true
   494     ^ true
   424 
   495 
   425     "Created: 21.6.1996 / 21:13:09 / cg"
   496     "Created: 21.6.1996 / 21:13:09 / cg"
   426 !
   497 !
   427 
   498 
   428 processTEXTChunkLen:len
   499 processTEXTChunkLen:len    
   429     inStream skip:len.
   500     "/ textual data in iso8859 coding.
       
   501 
       
   502     "/ currently ignored - not needed to display png images
       
   503     "/   Keyword:        1-79 bytes (character string)
       
   504     "/   Null separator: 1 byte
       
   505     "/   Text:           n bytes (character string)
       
   506 
       
   507     "/ if needed, set processTextChunks to true somewhere...
       
   508     processTextChunks == true ifTrue:[
       
   509         |chunkData keyword text i|
       
   510 
       
   511         chunkData := inStream nextBytes:len.
       
   512         i := chunkData indexOf:0.
       
   513         keyword := (chunkData copyTo:i-1) asString.
       
   514         text := (chunkData copyFrom:i+1) asString.
       
   515         self handleText:text keyword:keyword.
       
   516     ] ifFalse:[  
       
   517         inStream skip:len.
       
   518     ].    
   430     ^ true
   519     ^ true
   431 
   520 
   432     "Modified: 21.6.1996 / 21:15:27 / cg"
   521     "Modified: 21.6.1996 / 21:15:27 / cg"
   433 !
   522 !
   434 
   523 
   444     inStream skip:len.
   533     inStream skip:len.
   445     ^ true
   534     ^ true
   446 !
   535 !
   447 
   536 
   448 processZTXTChunkLen:len
   537 processZTXTChunkLen:len
       
   538     "/ compressed text
       
   539     
       
   540     "/ currently ignored - not needed to display png images
   449     inStream skip:len.
   541     inStream skip:len.
   450     ^ true
   542     ^ true
   451 
   543 
   452     "Created: 21.6.1996 / 21:15:58 / cg"
   544     "Created: 21.6.1996 / 21:15:58 / cg"
   453 ! !
   545 ! !
   919     ^ true
  1011     ^ true
   920 
  1012 
   921     "Modified: 21.6.1996 / 21:38:35 / cg"
  1013     "Modified: 21.6.1996 / 21:38:35 / cg"
   922 !
  1014 !
   923 
  1015 
       
  1016 handleText:text keyword:keyword
       
  1017     "/ things like exif data etc.
       
  1018     "/ self halt.
       
  1019 
       
  1020     "/Standard keywords for text chunks:
       
  1021     "/
       
  1022     "/   Title            Short (one line) title or caption for image
       
  1023     "/   Author           Name of image's creator
       
  1024     "/   Description      Description of image (possibly long)
       
  1025     "/   Copyright        Copyright notice
       
  1026     "/   Creation Time    Time of original image creation
       
  1027     "/   Software         Software used to create the image
       
  1028     "/   Disclaimer       Legal disclaimer
       
  1029     "/   Warning          Warning of nature of content
       
  1030     "/   Source           Device used to create the image
       
  1031     "/   Comment          Miscellaneous comment; conversion from
       
  1032     "/                    GIF comment
       
  1033 !
       
  1034 
   924 setColorType:colorType
  1035 setColorType:colorType
   925     colorType == 0 ifTrue:[
  1036     colorType == 0 ifTrue:[
   926         photometric := #blackIs0.
  1037         photometric := #blackIs0.
   927         samplesPerPixel := 1.
  1038         samplesPerPixel := 1.
   928         bitsPerSample := Array with:bitsPerChannel.
  1039         bitsPerSample := Array with:bitsPerChannel.