eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'JPEGReader':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: JPEGReader


Inheritance:

   Object
   |
   +--ImageReader
      |
      +--JPEGReader

Package:
stx:libview2
Category:
Graphics-Images-Readers
Version:
rev: 1.83 date: 2023/05/12 14:46:00
user: stefan
file: JPEGReader.st directory: libview2
module: stx stc-classLibrary: libview2

Description:


Reader for JPEG images.

This uses the libpeg library to read the image

Only writing of depth24 images is currently supported.

copyright

COPYRIGHT (c) 1993 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.

Class protocol:

class initialization
o  initialize
install myself in the Image classes fileFormat table
for the `.jpg' and '.jpeg' extensions.

defaults
o  defaultCompressQuality

o  defaultCompressQuality: percent

testing
o  canRepresent: anImage
return true, if anImage can be represented in my file format.
For now, only d24 images are supported.

o  isValidImageFile: aFilenameOrString
return true, if aFileName contains a JPG image.
Only look at the file's name here ...

Usage example(s):

     self isValidImageFile:'xxx.jpg'


Instance protocol:

accessing
o  app1SegmentHandler: aBlock
set a handler block for app1 segment data (geolocation in exif format)

o  compressQuality: compressQualityOrNilForDefault

o  forceDitherMode: something
set the dither mode, to one of #none or #ordered

o  forceGrayscale: something
set the forceGrayscale mode; if true, grayScale images are
returned, even if the input contains a color image.

private
o  app1SegmentCallback
return a callback function which invokes the app1SegmentHandlerBlock if defined.
This will be called to handle the exif segment, containing geolocation tags.
Return nil if there is no handler block defined

o  create_jpeg_compress_struct

o  create_jpeg_decompress_struct

o  decompressChunkInto: aByteArray startingAt: index

o  extractApp1DataFrom: data
= 'Exif' + 0-byte

o  extractExifDataFrom: data

o  fetchApp1SegmentData
msb first

o  finish_compress

o  finish_decompress

o  get_error_message

o  jpeg_getc

o  start_decompress

reading
o  fromStream: aStream
read a JPG image from a stream.
For now, we can only read from a stdio-FILE with libjpeg
(need to write a mem-reader to read from a Smalltalk stream).
Therefore, any internal stream data is copied to a temporary file first,
and libjpg asked to decompress from there.
This should be fixed, if jpeg reading is a bottleneck in your app.

Usage example(s):

     |stream|
     stream := #[] readWriteStream.
     '../../support/libjpeg-9/testimg.jpg' asFilename copyToStream:stream.
     JPEGReader fromStream:stream

Usage example(s):

     |stream reader|

     stream := '../../support/libjpeg-9/testimg.jpg' asFilename readStream.
     reader := JPEGReader new.
     reader forceGrayscale:true.
     reader forceDitherMode:#ordered.
     reader fromStream:stream.
     ^ reader image

writing
o  compressScanlines

o  save: anImage onFile: aFilenameOrFilenameString
ex return.

o  save: image onStream: aStream
save image in JPG-file-format onto aStream


Examples:


notice: for this kind of cartoon images, gif is actually more compact than jpeg (with reasonable quality) good quality:
 |i i24 i2|

 Transcript printf:'gif original %d\n' with:( '../../goodies/bitmaps/gifImages/garfield.gif' asFilename fileSize ).
 i := Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif'.
 i24 := Depth24Image fromImage:i.
 JPEGReader new
    save:i24
    onFile:'test100.jpg'
    quality:100.
 i2 := Image fromFile:'test100.jpg'.
 Transcript printf:'jpg 100%% %d\n' with:( 'test100.jpg' asFilename fileSize ).
 i2 inspect
normal (default) quality (which is 85):
 |i i24 i2|

 Transcript printf:'gif original %d\n' with:( '../../goodies/bitmaps/gifImages/garfield.gif' asFilename fileSize ).
 i := Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif'.
 i24 := Depth24Image fromImage:i.
 JPEGReader new
    save:i24
    onFile:'test80.jpg'.
 i2 := Image fromFile:'test80.jpg'.
 Transcript printf:'jpg 80%% %d\n' with:( 'test80.jpg' asFilename fileSize ).
 i2 inspect
low quality:
 |i i24 i2|

 i := Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif'.
 i24 := Depth24Image fromImage:i.
 JPEGReader new
    save:i24
    onStream:('test50.jpg' asFilename writeStream)
    quality:50.
 i2 := Image fromFile:'test50.jpg'.
 Transcript printf:'jpg 50%% %d\n' with:( 'test50.jpg' asFilename fileSize ).
 i2 inspect
bad quality:
 |i i24 i2|

 i := Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif'.
 i24 := Depth24Image fromImage:i.
 JPEGReader new
    save:i24
    onStream:('test20.jpg' asFilename writeStream)
    quality:20.
 i2 := Image fromFile:'test20.jpg'.
 Transcript printf:'jpg 20%% %d\n' with:( 'test20.jpg' asFilename fileSize ).
 i2 inspect
very bad quality:
 |i i24 i2|

 i := Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif'.
 i24 := Depth24Image fromImage:i.
 JPEGReader new
    save:i24
    onStream:('test10.jpg' asFilename writeStream)
    quality:10.
 i2 := Image fromFile:'test10.jpg'.
 Transcript printf:'jpg 10%% %d\n' with:( 'test10.jpg' asFilename fileSize ).
 i2 inspect
very very bad quality:
 |i i24 i2|

 i := Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif'.
 i24 := Depth24Image fromImage:i.
 JPEGReader new
    save:i24
    onStream:('test5.jpg' asFilename writeStream)
    quality:5.
 i2 := Image fromFile:'test5.jpg'.
 Transcript printf:'jpg 5%% %d\n' with:( 'test5.jpg' asFilename fileSize ).
 i2 inspect


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sun, 22 Dec 2024 04:59:30 GMT