Merge jv
authorMerge Script
Thu, 03 Mar 2016 06:57:42 +0100
branchjv
changeset 7177 03d926bea344
parent 7171 71c34a23762b (current diff)
parent 7176 047e717102d3 (diff)
child 7181 fb0cf59f68f9
Merge
Image.st
--- a/Image.st	Mon Feb 29 07:18:01 2016 +0000
+++ b/Image.st	Thu Mar 03 06:57:42 2016 +0100
@@ -1675,7 +1675,7 @@
                  However, a handler may provide a replacement image."
                 ^ ImageNotFoundQuerySignal
                             raiseRequestWith:fn
-                            errorString:('IMAGE [warning]: ''' , fn pathName, ''' does not exist or is not readable').
+                            errorString:('Image: ''' , fn pathName, ''' does not exist or is not readable').
             ].
         ].
         fn := inStream pathName asFilename.
@@ -1745,13 +1745,19 @@
         ].
     ].
 
+    (fn exists and:[fn isReadable]) ifFalse:[
+        ^ ImageNotFoundQuerySignal
+                    raiseRequestWith:fn
+                    errorString:('Image: ''' , fn pathName, ''' does not exist or is not readable').
+    ].
+    
     "nope - unknown format
      this signal is a query - if noone seems to care, return nil.
      However, a handler may provide a replacement image."
 
     ^ BadImageFormatQuerySignal
         raiseRequestWith:fn
-        errorString:(readersErrorMsg ? ('IMAGE [warning]: unknown image file format: ''' , aFileName asFilename pathName , '''')).
+        errorString:(readersErrorMsg ? ('Image: unknown image file format: ''' , fn pathName , '''')).
 
     "
      Image fromFile:'bitmaps/gifImages/claus.gif' inPackage:'stx:goodies'
@@ -1892,10 +1898,10 @@
      this format ...
     "
     MIMETypes imageReaderClasses do:[:readerClass |
-	readerClass notNil ifTrue:[
-	    image := readerClass fromStream:aStream.
-	    image notNil ifTrue:[^ image].
-	]
+        readerClass notNil ifTrue:[
+            image := readerClass fromStream:aStream.
+            image notNil ifTrue:[^ image].
+        ]
     ].
 
     "
@@ -1904,8 +1910,8 @@
 "/    'Image [info]: unknown image file format in stream: ' infoPrintCR.
 
     ^ ImageNotFoundQuerySignal
-		raiseRequestWith:aStream
-		errorString:('IMAGE [warning]: unknown image file format in stream').
+                raiseRequestWith:aStream
+                errorString:('Image [warning]: unknown image file format in stream').
 
     "
      Image fromFile:'goodies/bitmaps/gifImages/claus.gif'
@@ -1947,7 +1953,7 @@
 
     ^ ImageNotFoundQuerySignal
                 raiseRequestWith:aStream
-                errorString:('IMAGE: unknown image file format in stream').
+                errorString:('Image: unknown image file format in stream').
 
     "Created: 1.2.1997 / 14:46:20 / cg"
     "Modified: 1.2.1997 / 14:48:53 / cg"
@@ -14169,24 +14175,7 @@
      (see ImageReader subclasses implementing save:onFile:).
      May raise a signal, if the image cannot be written by the reader."
 
-    |suffix readerClass|
-
-    "/
-    "/ from the extension, get the imageReader class
-    "/ (which should know how to write images as well)
-    "/
-    suffix := aFileName asFilename suffix.
-    readerClass := MIMETypes imageReaderForSuffix:suffix.
-    readerClass notNil ifTrue:[
-        ^ self saveOn:aFileName using:readerClass
-    ].
-
-    "/
-    "/ no known extension - could ask user for the format here.
-    "/ currently default to tiff format.
-    "/
-    'Image [warning]: unknown extension - cannot figure out format - using default (tiff)' errorPrintCR.
-    ^ self saveOn:aFileName using:(self class defaultImageFileWriter)
+    ^ self saveOn:aFileName quality:nil
 
     "
      |image|
@@ -14201,12 +14190,50 @@
     "Modified: 30.6.1997 / 22:06:34 / cg"
 !
 
-saveOn:aFileName using:readerClass
+saveOn:aFileName quality:qualityPercentOrNil
+    "save the image in aFileName. The suffix of the filename controls the format.
+     Currently, not all formats may be supported
+     (see ImageReader subclasses implementing save:onFile:).
+     May raise a signal, if the image cannot be written by the reader."
+
+    |suffix readerClass|
+
+    "/
+    "/ from the extension, get the imageReader class
+    "/ (which should know how to write images as well)
+    "/
+    suffix := aFileName asFilename suffix.
+    readerClass := MIMETypes imageReaderForSuffix:suffix.
+    readerClass isNil ifTrue:[        
+        "/
+        "/ no known extension - could ask user for the format here.
+        "/ currently default to tiff format.
+        "/
+        readerClass := self class defaultImageFileWriter.
+        'Image [warning]: unknown extension - cannot figure out format - using default (',readerClass name,')' errorPrintCR.
+    ].
+    ^ self saveOn:aFileName quality:qualityPercentOrNil using:readerClass
+
+
+    "
+     |image|
+
+     image := Image fromFile:'goodies/bitmaps/RCube.tiff'.
+     image saveOn:'myImage.tiff'.
+     image saveOn:'myImage.xbm'.
+     image saveOn:'myImage.xpm'.
+     image saveOn:'myImage.xwd'.
+    "
+
+    "Modified: 30.6.1997 / 22:06:34 / cg"
+!
+
+saveOn:aFileName quality:qualityPercentOrNil using:readerClass
     "save the receiver using the representation class
      (which is usually a concrete subclasses of ImageReader).
      May raise a signal, if the image cannot be written by the reader."
 
-    ^ readerClass save:self onFile:aFileName
+    ^ readerClass save:self onFile:aFileName quality:qualityPercentOrNil
 
     "
      |anImage|
@@ -14227,9 +14254,61 @@
 
      anImage := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'.
      Image cannotRepresentImageSignal handle:[:ex |
-	self warn:'cannot save the image in this format'
+        self warn:'cannot save the image in this format'
      ] do:[
-	anImage saveOn:'myImage.xbm' using:XBMReader.
+        anImage saveOn:'myImage.xbm' using:XBMReader.
+     ]
+    "
+
+    "
+     |anImage|
+
+     anImage := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'.
+     anImage saveOn:'myImage.xpm' using:XPMReader.
+    "
+
+    "
+     |anImage|
+
+     anImage := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'.
+     anImage saveOn:'myImage.gif' using:GIFReader.
+    "
+
+    "Modified: 10.4.1997 / 17:49:26 / cg"
+!
+
+saveOn:aFileName using:readerClass
+    "save the receiver using the representation class
+     (which is usually a concrete subclasses of ImageReader).
+     May raise a signal, if the image cannot be written by the reader."
+
+    ^ readerClass save:self onFile:aFileName quality:nil
+
+    "
+     |anImage|
+
+     anImage := Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif'.
+     anImage saveOn:'myImage.tiff' using:TIFFReader.
+     (Depth24Image fromImage:anImage) saveOn:'myImage.jpg' using:JPEGReader.
+     anImage saveOn:'myImage50.tiff' quality:50 using:TIFFReader.
+     (Depth24Image fromImage:anImage) saveOn:'myImage50.jpg' quality:50 using:JPEGReader.
+    "
+
+    "
+     |anImage|
+
+     anImage := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'.
+     anImage saveOn:'myImage.xbm' using:XBMReader.
+    "
+
+    "
+     |anImage|
+
+     anImage := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'.
+     Image cannotRepresentImageSignal handle:[:ex |
+        self warn:'cannot save the image in this format'
+     ] do:[
+        anImage saveOn:'myImage.xbm' using:XBMReader.
      ]
     "
 
--- a/ImageReader.st	Mon Feb 29 07:18:01 2016 +0000
+++ b/ImageReader.st	Thu Mar 03 06:57:42 2016 +0100
@@ -913,18 +913,20 @@
 
 documentation
 "
-    Abstract class to provide common functions for image-readers
-    (i.e. TIFFReader, GIFReader etc.). In contrast to what the name suggests,
-    ImageReaders are suposed to support both reading and writing of images
+    Abstract class to provide common functions for image-readers/writers.
+    (i.e. TIFFReader, GIFReader etc.).
+    
+    In contrast to what the name suggests, ImageReaders are supposed to support 
+    both reading and writing of images
     (i.e. the name is somewhat outdated, but kept for historic and backward
-    compatibility reasons). They provide functionality similar to Squeak's
-    ImageReaderWriter classes.
+    compatibility reasons). 
+    They provide functionality similar to Squeak's ImageReaderWriter classes.
 
     ImageReaders are created temporary to read an image from a stream.
     Normally, they are not directly used - instead, the image class is
     asked to read some file, and return an instance for it:
-	Image fromFile:<someFileName>
-    The Image class will guess the images format and forward the task to
+        Image fromFile:<someFileName>
+    The Image class will guess the image's format and forward the task to
     some concrete ImageReaderClass.
     If that class thinks, that the file's format is incorrect,
     other readers are tried until some reader class finds the file's format acceptable.
@@ -935,9 +937,9 @@
 
     See the implementation of #fromStream: in concrete subclasses.
     The public interfaces are:
-	 <ConcreteReaderClass> fromFile:aFilename
+         <ConcreteReaderClass> fromFile:aFilename
     or:
-	 <ConcreteReaderClass> fromStream:aStream
+         <ConcreteReaderClass> fromStream:aStream
 
     If you add a new reader, don't forget to add the method #isValidImageFile:
     which should return true, if this reader supports reading a given file.
@@ -945,11 +947,15 @@
     If your new reader class supports writing files, don't forget to add
     #canRepresent:anImage and return true from this method.
 
+    writing:
+        tell the image, to save itself, via <image> saveOn:fileName
+        or <image> saveOn:fileName using:<readerClass>
+        
     [See also:]
-	Image Icon Form
+        Image Icon Form
 
     [author:]
-	Claus Gittinger
+        Claus Gittinger
 "
 ! !
 
@@ -1629,12 +1635,37 @@
     "Modified: 10.4.1997 / 17:42:57 / cg"
 !
 
+save:anImage onFile:aFileName quality:qualityPercent
+    "save the image in my format on aFileName.
+     qualityPercent is ignored by all lossless formats.
+     JPG does care for it."
+
+    ^ (self basicNew) save:anImage onFile:aFileName quality:qualityPercent
+
+    "Modified: 10.4.1997 / 17:42:57 / cg"
+!
+
 save:anImage onStream:aStream
     "save the image in my format on a Stream"
 
     ^ (self basicNew) save:anImage onStream:aStream
 
     "Modified: 10.4.1997 / 17:42:57 / cg"
+!
+
+save:anImage onStream:aStream quality:qualityPercent
+    "save the image in my format on a Stream.
+     qualityPercent is ignored by all lossless formats.
+     JPG does care for it."
+
+    ^ (self basicNew) save:anImage onStream:aStream quality:qualityPercent
+
+    "
+     (Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif') saveOn:'garfield.gif' 
+     (Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif') saveOn:'garfield.jpg' 
+     (Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif') saveOn:'garfield50.jpg' quality:50
+     (Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif') saveOn:'garfield100.jpg' quality:100
+    "
 ! !
 
 !ImageReader class methodsFor:'testing'!
@@ -1702,6 +1733,10 @@
     "Modified: 22.4.1996 / 19:15:24 / cg"
 !
 
+compressQuality:qualityPercentIgnoredHere
+    "/ intentionally ignored here (redefined in JPEGReader)
+!
+
 data
     "return the raw image data"
 
@@ -1991,18 +2026,33 @@
     "save image in my format on aFile"
 
     self writingFile:aFileName for:image do:[:stream |
-	self save:image onStream:stream.
+        self save:image onStream:stream.
     ].
+!
+
+save:image onFile:aFileName quality:qualityPercentOrNil
+    "save image in my format on aFile"
+
+    self compressQuality:qualityPercentOrNil.
+    self save:image onFile:aFileName
 
     "Modified: / 01-06-2010 / 19:02:17 / cg"
 !
 
 save:image onStream:aStream
-    "save image in my format on a Stream"
+    "save image in my file-format onto aStream"
 
     ^ Image cannotRepresentImageSignal
-	raiseWith:image
-	errorString:('image save not implemented/supported for this format').
+        raiseWith:image
+        errorString:('image save not implemented/supported for this format').
+!
+
+save:image onStream:aStream quality:qualityPercentOrNil
+    "save image in my format on a Stream.
+     QualityPercent is ignored by lossless formats (jpg uses it)"
+
+    self compressQuality:qualityPercentOrNil.
+    self save:image onStream:aStream
 !
 
 saveAll:aCollectionOfImages onFile:aFileName