' .ApplicationSource PNM-Reader(1.2)'! 'From VisualWorks(R) Release 2.0 of 4 August 1994 on 31 March 1995 at 6:00:52 am'! '- sources of PNM-Reader(1.2) -'! ImageReader subclass: #PNMImageReader instanceVariableNames: 'asciiFlag ' classVariableNames: '' poolDictionaries: '' category: 'Graphics-Images'! !PNMImageReader methodsFor: 'attributes'! format "Answer a string naming the format used to store the image." ^'Portable aNy Map (PNM)'! ! !PNMImageReader methodsFor: 'private-subclass responsibilty'! initializePalette ^self subclassResponsibility! nextPixelValue ^self subclassResponsibility! readParameters ^self subclassResponsibility! ! !PNMImageReader methodsFor: 'private'! magicNumbers ^self class magicNumbers! readImageData | pixelValue | asciiFlag ifFalse: [ioStream upTo: Character cr. ioStream binary]. (0 to: height - 1) do: [:y | (0 to: width - 1) do: [:x | pixelValue := self nextPixelValue. image atPoint: x @ y put: pixelValue]]! skipJunk ioStream skipSeparators. [ioStream peek = $#] whileTrue: [ioStream upTo: Character cr]. ioStream skipSeparators.! ! !PNMImageReader methodsFor: 'initialize-release'! readImage "Read the image stored the input stream." "import Portable aNyMap (PNM) format as of Jef Poskanzers Portable Bitmap Package." | pnmType | Stream endOfStreamSignal handle: [:ex | ex restartDo: [self formatError: 'Image data ended prematurely.']] do: [ioStream text. pnmType := (ioStream next: 2) asSymbol. asciiFlag := pnmType = (self magicNumbers at: 1). self readParameters. self initializePalette. self initializeImage. self readImageData]! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! !PNMImageReader class methodsFor: 'private'! checkFileExtensionFor: aFilenameOrString ^'*.pnm' match: aFilenameOrString asString! magicNumbers "Answer the right magic numbers for this class (See also class protocol>documentation)." ^#()! ! !PNMImageReader class methodsFor: 'documentation'! pnmFiles "The following is the UNIX manual page on pnm: NAME pnm - portable anymap file format DESCRIPTION The pnm programs operate on portable bitmaps, graymaps, and pixmaps, produced by the PBM, PGM, and PPM toolkits. There is no file format associated with pnm itself."! ! PNMImageReader subclass: #PPMImageReader instanceVariableNames: 'bitsPerColor ' classVariableNames: '' poolDictionaries: '' category: 'Graphics-Images'! !PPMImageReader methodsFor: 'private'! initializePalette | mask | mask := self makeMask. palette := FixedPalette redShift: 0 redMask: mask greenShift: bitsPerColor greenMask: mask blueShift: bitsPerColor * 2 blueMask: mask! makeMask "Answers a bit mask with the least bitsPerColor bits set." ^(2 raisedTo: bitsPerColor) - 1! nextPixelValue | red green blue | asciiFlag ifTrue: [self skipJunk. red := Integer readFrom: ioStream. self skipJunk. green := Integer readFrom: ioStream. self skipJunk. blue := Integer readFrom: ioStream] ifFalse: [red := ioStream next. green := ioStream next. blue := ioStream next]. ^((blue bitShift: bitsPerColor * 2) bitOr: (green bitShift: bitsPerColor)) bitOr: red.! readParameters "Read image parameters" | w h maxValue | self skipJunk. w := Integer readFrom: ioStream. self skipJunk. h := Integer readFrom: ioStream. self skipJunk. maxValue := Integer readFrom: ioStream. bitsPerColor := (maxValue + 1 log: 2) ceiling. "for each of r, g, b" self width: w height: h bitsPerPixel: bitsPerColor * 3! ! !PPMImageReader methodsFor: 'attributes'! format "Answer a string naming the format used to store the image." ^'Portable Pixmap (PPM)'! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! !PPMImageReader class methodsFor: 'documentation'! ppmFiles "The following is the UNIX manual page on ppm: NAME ppm - portable pixmap file format DESCRIPTION The portable pixmap format is a lowest common denominator color image file format. The definition is as follows: - A 'magic number' for identifying the file type. A ppm file's magic number is the two characters 'P3'. - Whitespace (blanks, TABs, CRs, LFs). - A width, formatted as ASCII characters in decimal. - Whitespace. - A height, again in ASCII decimal. - Whitespace. - The maximum color-component value, again in ASCII decimal. - Whitespace. - Width * height pixels, each three ASCII decimal values between 0 and the specified maximum value, starting at the top-left corner of the pixmap, proceding in normal English reading order. The three values for each pixel represent red, green, and blue, respectively; a value of 0 means that color is off, and the maximum value means that color is maxxed out. - Characters from a '#' to the next end-of-line are ignored (comments). - No line should be longer than 70 characters. Here is an example of a small pixmap in this format: P3 # feep.ppm 4 4 15 0 0 0 0 0 0 0 0 0 15 0 15 0 0 0 0 15 7 0 0 0 0 0 0 0 0 0 0 0 0 0 15 7 0 0 0 15 0 15 0 0 0 0 0 0 0 0 0 Programs that read this format should be as lenient as pos- sible, accepting anything that looks remotely like a pixmap. There is also a variant on the format, available by setting the RAWBITS option at compile time. This variant is dif- ferent in the following ways: - The 'magic number' is 'P6' instead of 'P3'. - The pixel values are stored as plain bytes, instead of ASCII decimal. - Whitespace is not allowed in the pixels area. - The files are smaller and many times faster to read and write. Note that this raw format can only be used for maxvals less than or equal to 255. If you use the PPM library and try to write a file with a larger maxval, it will automatically fall back on the slower but more general ASCII format."! ! !PPMImageReader class methodsFor: 'private'! canRead: aFilenameOrString "Answer whether the receiver can read the named file." | pattern | pattern := #('*.ppm') detect: [:p | p match: aFilenameOrString asString] ifNone: [nil]. pattern notNil ifTrue: [^true]. ^Object errorSignal handle: [:ex | ex returnWith: false] do: [| inputStream | inputStream := aFilenameOrString asFilename readStream text. [self magicNumbers includes: (inputStream next: 2)] valueNowOrOnUnwindDo: [inputStream close]]! checkFileExtensionFor: aFilenameOrString ^'*.ppm' match: aFilenameOrString asString! magicNumbers "Answer the right magic numbers for this class (See also class protocol>documentation)." ^#(P3 P6)! ! PNMImageReader subclass: #PGMImageReader instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Graphics-Images'! !PGMImageReader methodsFor: 'attributes'! format "Answer a string naming the format used to store the image." ^'Portable Grayscale Map (PGM)'! ! !PGMImageReader methodsFor: 'private'! initializePalette | colors | colors := Array new: (2 raisedTo: bitsPerPixel). 1 to: colors size do: [:i | colors at: i put: (ColorValue brightness: i - 1 / (colors size - 1))]. palette := MappedPalette withColors: colors.! nextPixelValue ^asciiFlag ifTrue: [self skipJunk. Integer readFrom: ioStream] ifFalse: [ioStream next]! readParameters "Read image parameters" | w h maxValue bpp | self skipJunk. w := Integer readFrom: ioStream. self skipJunk. h := Integer readFrom: ioStream. self skipJunk. maxValue := Integer readFrom: ioStream. bpp := (maxValue + 1 log: 2) ceiling. self width: w height: h bitsPerPixel: bpp.! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! !PGMImageReader class methodsFor: 'documentation'! pgmFiles "The following is the UNIX manual page on pgm: NAME pgm - portable graymap file format DESCRIPTION The portable graymap format is a lowest common denominator grayscale file format. The definition is as follows: - A 'magic number' for identifying the file type. A pgm file's magic number is the two characters 'P2'. - Whitespace (blanks, TABs, CRs, LFs). - A width, formatted as ASCII characters in decimal. - Whitespace. - A height, again in ASCII decimal. - Whitespace. - The maximum gray value, again in ASCII decimal. - Whitespace. - Width * height gray values, each in ASCII decimal, between 0 and the specified maximum value, separated by whi- tespace, starting at the top-left corner of the graymap, proceding in normal English reading order. A value of 0 means black, and the maximum value means white. - Characters from a '#' to the next end-of-line are ignored (comments). - No line should be longer than 70 characters. Here is an example of a small graymap in this format: P2 # feep.pgm 24 7 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0 0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0 0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0 0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0 0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Programs that read this format should be as lenient as pos- sible, accepting anything that looks remotely like a gray- map. There is also a variant on the format, available by setting the RAWBITS option at compile time. This variant is dif- ferent in the following ways: - The 'magic number' is 'P5' instead of 'P2'. - The gray values are stored as plain bytes, instead of ASCII decimal. - No whitespace is allowed in the grays section. - The files are smaller and many times faster to read and write. Note that this raw format can only be used for maxvals less than or equal to 255. If you use the PGM library and try to write a file with a larger maxval, it will automatically fall back on the slower but more general ASCII format."! ! !PGMImageReader class methodsFor: 'private'! canRead: aFilenameOrString "Answer whether the receiver can read the named file." ('*.pgm' match: aFilenameOrString asString) ifTrue: [^true]. ^Object errorSignal handle: [:ex | ex returnWith: false] do: [| inputStream | inputStream := aFilenameOrString asFilename readStream text. [self magicNumbers includes: (inputStream next: 2) asSymbol] valueNowOrOnUnwindDo: [inputStream close]]! checkFileExtensionFor: aFilenameOrString ^('*.pgm' match: aFilenameOrString asString)! magicNumbers "Answer the right magic numbers for this class (See also class protocol>documentation)." ^#( P2 P5 )! ! PNMImageReader subclass: #PBMImageReader instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Graphics-Images'! !PBMImageReader methodsFor: 'attributes'! format "Answer a string naming the format used to store the image." ^'Portable Bitmap (PBM)'! ! !PBMImageReader methodsFor: 'private'! initializePalette palette := MappedPalette monochromeDefault! nextPixelValue ^asciiFlag ifTrue: [self skipJunk. Integer readFrom: ioStream] ifFalse: [self error: 'internal error: should never read raw data with method nextPixelValue']! readImageData asciiFlag ifTrue: [^super readImageData]. ioStream upTo: Character cr. ioStream binary. (0 to: height - 1) do: [:y | self readPackedRow: y]! readPackedRow: row "Read a pixelrow of the 1-bit-deep image. Each byte contains 8 pixels." | packedRow | packedRow := ByteArray new: bytesPerRow. (1 to: rowEndOffset + 1) do: [:i | | byte | byte := ioStream next. "byte := self mirror: byte." packedRow at: i put: byte]. image packedRowAt: row putAll: packedRow! readParameters "Read image parameters." | w h | self skipJunk. w := Integer readFrom: ioStream. self skipJunk. h := Integer readFrom: ioStream. self width: w height: h bitsPerPixel: 1! ! !PBMImageReader methodsFor: 'initialize-release'! readImage "Read the image stored the input stream." | pnmType | Stream endOfStreamSignal handle: [:ex | ex restartDo: [self formatError: 'Image data ended prematurely.']] do: [ioStream text. pnmType := (ioStream next: 2) asSymbol. asciiFlag := pnmType = (self magicNumbers at: 1). self readParameters. self initializePalette. self initializeImage. self readImageData]! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! !PBMImageReader class methodsFor: 'private'! canRead: aFilenameOrString "Answer whether the receiver can read the named file." | pattern | pattern := #('*.pbm') detect: [:p | p match: aFilenameOrString asString] ifNone: [nil]. pattern notNil ifTrue: [^true]. ^Object errorSignal handle: [:ex | ex returnWith: false] do: [| inputStream | inputStream := aFilenameOrString asFilename readStream text. [self magicNumbers includes: (inputStream next: 2) asSymbol] valueNowOrOnUnwindDo: [inputStream close]]! checkFileExtensionFor: aFilenameOrString ^'*.pbm' match: aFilenameOrString asString! magicNumbers "Answer the right magic numbers for this class (See also class protocol>documentation)." ^#(#P1 #P4)! ! !PBMImageReader class methodsFor: 'documentation'! pbmFiles "The following is the UNIX manual page on pbm: NAME pbm - portable bitmap file format DESCRIPTION The portable bitmap format is a lowest common denominator monochrome file format. It was originally designed to make it reasonable to mail bitmaps between different types of machines using the typical stupid network mailers we have today. Now it serves as the common language of a large fam- ily of bitmap conversion filters. The definition is as fol- lows: - A 'magic number' for identifying the file type. A pbm file's magic number is the two characters 'P1'. - Whitespace (blanks, TABs, CRs, LFs). - A width, formatted as ASCII characters in decimal. - Whitespace. - A height, again in ASCII decimal. - Whitespace. - Width * height bits, each either '1' or '0', starting at the top-left corner of the bitmap, proceding in normal English reading order. - The character '1' means black, '0' means white. - Whitespace in the bits section is ignored. - Characters from a '#' to the next end-of-line are ignored (comments). - No line should be longer than 70 characters. Here is an example of a small bitmap in this format: P1 # feep.pbm 24 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Programs that read this format should be as lenient as pos- sible, accepting anything that looks remotely like a bitmap. There is also a variant on the format, available by setting the RAWBITS option at compile time. This variant is dif- ferent in the following ways: - The 'magic number' is 'P4' instead of 'P1'. - The bits are stored eight per byte, high bit first low bit last. - No whitespace is allowed in the bits section. - The files are eight times smaller and many times faster to read and write."! !