JPEGReader.st
changeset 1061 e487ecc3d506
parent 951 de8417214dfd
child 1070 9c845473f95d
--- a/JPEGReader.st	Thu Sep 03 15:09:40 1998 +0200
+++ b/JPEGReader.st	Tue Sep 08 12:10:47 1998 +0200
@@ -32,6 +32,11 @@
 # include <sys/types.h>
 #endif
 
+#ifdef WIN32
+# undef longjmp
+# undef setjmp
+#endif
+
 #include <jpeglib.h>
 #include <jerror.h>
 
@@ -40,28 +45,46 @@
 	jmp_buf setjmp_buffer;
 };
 
-static my_error_exit(cinfo)
-    j_common_ptr cinfo;
-{
-    struct my_error_mgr *myerrPtr = (struct my_error_mgr *) cinfo->err;
-
-    if (@global(ErrorPrinting) == true) {
-	fprintf(stderr, "JPEGReader [warning]: jpeg error\n"); 
-    }
-    longjmp(myerrPtr->setjmp_buffer, 1);
-}
-
 %}
 ! !
 
 !JPEGReader primitiveFunctions!
 %{
 
-/* 
+/*
  * any local C (helper) functions
  * come here (please, define as static)
  */
 
+static
+my_error_exit(cinfo)
+    j_common_ptr cinfo;
+{
+    struct my_error_mgr *myerrPtr = (struct my_error_mgr *) cinfo->err;
+
+    if (@global(ErrorPrinting) == true) {
+	fprintf(stderr, "JPEGReader [warning]: jpeg error\n");
+    }
+    longjmp(myerrPtr->setjmp_buffer, 1);
+}
+
+static
+my_output_message(cinfo)
+    j_common_ptr cinfo;
+{
+    char buffer[JMSG_LENGTH_MAX];
+
+    if (@global(ErrorPrinting) == true) {
+	fprintf(stderr, "libJPEG [error]: ");
+
+       /* Create the message */
+       (*cinfo->err->format_message) (cinfo, buffer);
+
+       /* Send it to stderr, adding a newline */
+       fprintf(stderr, "%s\n", buffer);
+    }
+}
+
 /*
  * Optional progress monitor: display a percent-done figure on stderr.
  */
@@ -79,8 +102,8 @@
     prog->percent_done = percent_done;
     if (total_passes > 1) {
       fprintf(stderr, "\rPass %d/%d: %3d%% ",
-              prog->pub.completed_passes + prog->completed_extra_passes + 1,
-              total_passes, percent_done);
+	      prog->pub.completed_passes + prog->completed_extra_passes + 1,
+	      total_passes, percent_done);
     } else {
       fprintf(stderr, "\r %3d%% ", percent_done);
     }
@@ -143,10 +166,10 @@
     Only reading of files is supported.
 
     [See also:]
-        Image Form Icon
-        BlitImageReader FaceReader GIFReader PBMReader PCXReader 
-        ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader 
-        XBMReader XPMReader XWDReader 
+	Image Form Icon
+	BlitImageReader FaceReader GIFReader PBMReader PCXReader 
+	ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader 
+	XBMReader XPMReader XWDReader 
 "
 ! !
 
@@ -202,8 +225,8 @@
 
     fp := inStream filePointer.
     fp isNil ifTrue:[
-        self error:'can only read from an external stream'.
-        ^ self.
+	self error:'can only read from an external stream'.
+	^ self.
     ].
 
 %{
@@ -224,13 +247,13 @@
 
     if (__isExternalBytes(j_d_s)
      && __isExternalBytes(j_e_m)) {
-        cinfoPtr = (struct jpeg_decompress_struct *)(__externalBytesAddress(j_d_s));
-        jerrPtr = (struct my_error_mgr *)(__externalBytesAddress(j_e_m));
+	cinfoPtr = (struct jpeg_decompress_struct *)(__externalBytesAddress(j_d_s));
+	jerrPtr = (struct my_error_mgr *)(__externalBytesAddress(j_e_m));
 
-        /* 
-         * Initialize the JPEG decompression object with default error handling.
-         */
-        cinfoPtr->err = jpeg_std_error(jerrPtr);
+	/* 
+	 * Initialize the JPEG decompression object with default error handling.
+	 */
+	cinfoPtr->err = jpeg_std_error(jerrPtr);
 
 	/*
 	 * prepare to handle errors smoothly ...
@@ -244,83 +267,88 @@
 	    RETURN (false);
 	}
 
-        jpeg_create_decompress(cinfoPtr);
+       /*
+        * use my message print function
+        */
+       jerrPtr->pub.output_message = my_output_message;
+
+	jpeg_create_decompress(cinfoPtr);
 #if 0
-        /* 
-         * Insert custom COM marker processor.
-         */
-        jpeg_set_marker_processor(cinfoPtr, JPEG_COM, COM_handler);
+	/* 
+	 * Insert custom COM marker processor.
+	 */
+	jpeg_set_marker_processor(cinfoPtr, JPEG_COM, COM_handler);
 #endif
-        cinfoPtr->err->trace_level = 0;
+	cinfoPtr->err->trace_level = 0;
 
 #if 0
-        /* colors setting */
-        cinfoPtr->desired_number_of_colors = val;
-        cinfoPtr->quantize_colors = TRUE;
+	/* colors setting */
+	cinfoPtr->desired_number_of_colors = val;
+	cinfoPtr->quantize_colors = TRUE;
 #endif
 #if 0
-        /* dct setting */
-        cinfoPtr->dct_method = JDCT_ISLOW;
-        or: cinfoPtr->dct_method = JDCT_IFAST;
-        or: cinfoPtr->dct_method = JDCT_FLOAT;
+	/* dct setting */
+	cinfoPtr->dct_method = JDCT_ISLOW;
+	or: cinfoPtr->dct_method = JDCT_IFAST;
+	or: cinfoPtr->dct_method = JDCT_FLOAT;
 #endif
 
-        /* dither setting */
-        cinfoPtr->dither_mode = JDITHER_FS;
-        if (__INST(forceDitherMode) == @symbol(none)) {
-            cinfoPtr->dither_mode = JDITHER_NONE;
-        } else {
-            if (__INST(forceDitherMode) == @symbol(ordered)) {
-                cinfoPtr->dither_mode = JDITHER_ORDERED;
-            }
-        }
+	/* dither setting */
+	cinfoPtr->dither_mode = JDITHER_FS;
+	if (__INST(forceDitherMode) == @symbol(none)) {
+	    cinfoPtr->dither_mode = JDITHER_NONE;
+	} else {
+	    if (__INST(forceDitherMode) == @symbol(ordered)) {
+		cinfoPtr->dither_mode = JDITHER_ORDERED;
+	    }
+	}
 
 #if 0
-        /* fast setting */
-        cinfoPtr->two_pass_quantize = FALSE;
-        cinfoPtr->dither_mode = JDITHER_ORDERED;
-        cinfoPtr->desired_number_of_colors = 216;
-        cinfoPtr->dct_method = JDCT_FASTEST;
-        cinfoPtr->do_fancy_upsampling = FALSE;
+	/* fast setting */
+	cinfoPtr->two_pass_quantize = FALSE;
+	cinfoPtr->dither_mode = JDITHER_ORDERED;
+	cinfoPtr->desired_number_of_colors = 216;
+	cinfoPtr->dct_method = JDCT_FASTEST;
+	cinfoPtr->do_fancy_upsampling = FALSE;
 #endif
 
-        if (__INST(forceGrayscale) == true) {
-            /* grayscale setting */
-            cinfoPtr->out_color_space = JCS_GRAYSCALE;
-        }
+	if (__INST(forceGrayscale) == true) {
+	    /* grayscale setting */
+	    cinfoPtr->out_color_space = JCS_GRAYSCALE;
+	}
 
 #if 0
-        /* maxmemory setting */
-        cinfoPtr->mem->max_memory_to_use = lval * 1000L;
+	/* maxmemory setting */
+	cinfoPtr->mem->max_memory_to_use = lval * 1000L;
 #endif
 
 #if 0
-        /* nosmooth setting */
-        cinfoPtr->do_fancy_upsampling = FALSE;
+	/* nosmooth setting */
+	cinfoPtr->do_fancy_upsampling = FALSE;
 #endif
 
 #if 0
-        /* onepass setting */
-        cinfoPtr->two_pass_quantize = FALSE;
+	/* onepass setting */
+	cinfoPtr->two_pass_quantize = FALSE;
 #endif
 
-        /* Specify data source for decompression */
-        jpeg_stdio_src(cinfoPtr, f);
+	/* Specify data source for decompression */
+	jpeg_stdio_src(cinfoPtr, f);
 
-        /* Read file header, set default decompression parameters */
-        (void) jpeg_read_header(cinfoPtr, TRUE);
+	/* Read file header, set default decompression parameters */
+	(void) jpeg_read_header(cinfoPtr, TRUE);
 
-        /* Calculate output image dimensions so we can allocate space */
-        jpeg_calc_output_dimensions(cinfoPtr);
+	/* Calculate output image dimensions so we can allocate space */
+	jpeg_calc_output_dimensions(cinfoPtr);
 
-        __INST(width) = __MKSMALLINT(cinfoPtr->output_width);
-        __INST(height) = __MKSMALLINT(cinfoPtr->output_height);
-        __INST(colorComponents) = __MKSMALLINT(cinfoPtr->output_components);
+	__INST(width) = __MKSMALLINT(cinfoPtr->output_width);
+	__INST(height) = __MKSMALLINT(cinfoPtr->output_height);
+	__INST(colorComponents) = __MKSMALLINT(cinfoPtr->output_components);
 
 #if 0
-        /* could now set additional values in cinfo
-         * (colormap)
-         */
+	/* could now set additional values in cinfo
+	 * (colormap)
+	 */
 #endif
 
     }
@@ -332,43 +360,49 @@
 %{
     struct jpeg_decompress_struct *cinfoPtr;
     struct my_error_mgr *jerrPtr;
-    char *rowPtr;
+    char *rowPtr = NULL;
     OBJ j_d_s = __INST(jpeg_decompress_struct);
     OBJ j_e_m = __INST(jpeg_error_mgr_struct);
     int num_scanlines;
     char *rowPointers[4];
 
+
+    if (__isByteArray(aByteArray)) {
+        rowPtr = (char *)(__ByteArrayInstPtr(aByteArray)->ba_element);
+    } else if (__isExternalBytes(aByteArray)) {
+        rowPtr = __externalBytesAddress(aByteArray);
+    }
+
     if (__isExternalBytes(j_d_s)
-     && __isByteArray(aByteArray)
+     && (rowPtr != NULL)
      && __isExternalBytes(j_e_m)) {
-        cinfoPtr = (struct jpeg_decompress_struct *)(__externalBytesAddress(j_d_s));
-        jerrPtr = (struct my_error_mgr *)(__externalBytesAddress(j_e_m));
-
-        rowPtr = (char *)(__ByteArrayInstPtr(aByteArray)->ba_element);
-        rowPtr += __intVal(index) - 1;
+	cinfoPtr = (struct jpeg_decompress_struct *)(__externalBytesAddress(j_d_s));
+	jerrPtr = (struct my_error_mgr *)(__externalBytesAddress(j_e_m));
 
-        rowPointers[0] = rowPtr;
-        rowPointers[1] = NULL;
-        rowPointers[2] = NULL;
-        rowPointers[3] = NULL;
+	rowPtr += __intVal(index) - 1;
 
-        if (cinfoPtr->output_scanline < cinfoPtr->output_height) {
-            if (setjmp(jerrPtr->setjmp_buffer)) {
-                /* 
-                 * error occurred ...
-                 */
+	rowPointers[0] = rowPtr;
+	rowPointers[1] = NULL;
+	rowPointers[2] = NULL;
+	rowPointers[3] = NULL;
+
+	if (cinfoPtr->output_scanline < cinfoPtr->output_height) {
+	    if (setjmp(jerrPtr->setjmp_buffer)) {
+		/* 
+		 * error occurred ...
+		 */
 		jpeg_destroy_decompress(cinfoPtr);
 		RETURN (__MKSMALLINT(-1));
 	    }
-            num_scanlines = jpeg_read_scanlines(cinfoPtr, 
-                                                rowPointers,
-                                                1);
-            RETURN (__MKSMALLINT(num_scanlines));
-        }
-        RETURN (__MKSMALLINT(0));
+	    num_scanlines = jpeg_read_scanlines(cinfoPtr, 
+						rowPointers,
+						1);
+	    RETURN (__MKSMALLINT(num_scanlines));
+	}
+	RETURN (__MKSMALLINT(0));
     }
 %}.
-    self halt.
+    self halt:'bad arguments'.
 !
 
 finish_decompress
@@ -380,7 +414,7 @@
 
     if (__isExternalBytes(j_d_s)
      && __isExternalBytes(j_e_m)) {
-        cinfoPtr = (struct jpeg_decompress_struct *)(__externalBytesAddress(j_d_s));
+	cinfoPtr = (struct jpeg_decompress_struct *)(__externalBytesAddress(j_d_s));
 	jerrPtr = (struct my_error_mgr *)(__externalBytesAddress(j_e_m));
 
 	if (setjmp(jerrPtr->setjmp_buffer)) {
@@ -388,9 +422,9 @@
 	    RETURN (false);
 	}
 
-        /* finish decompressor */
-        (void) jpeg_finish_decompress(cinfoPtr);
-        (void) jpeg_destroy_decompress(cinfoPtr);
+	/* finish decompressor */
+	(void) jpeg_finish_decompress(cinfoPtr);
+	(void) jpeg_destroy_decompress(cinfoPtr);
 	RETURN (true);
     }
 %}
@@ -422,7 +456,7 @@
 
     if (__isExternalBytes(j_d_s)
      && __isExternalBytes(j_e_m)) {
-        cinfoPtr = (struct jpeg_decompress_struct *)(__externalBytesAddress(j_d_s));
+	cinfoPtr = (struct jpeg_decompress_struct *)(__externalBytesAddress(j_d_s));
 	jerrPtr = (struct my_error_mgr *)(__externalBytesAddress(j_e_m));
 
 	if (setjmp(jerrPtr->setjmp_buffer)) {
@@ -430,8 +464,8 @@
 	    RETURN (false);
 	}
 
-        /* Start decompressor */
-        (void) jpeg_start_decompress(cinfoPtr);
+	/* Start decompressor */
+	(void) jpeg_start_decompress(cinfoPtr);
 	RETURN (true);
     }
 %}
@@ -445,22 +479,22 @@
     |dataIdx bytesPerRow returnCode pos1 ok tmpFile s|
 
     aStream isExternalStream ifFalse:[
-        "/ libJpeg can only handle real OS-streams
+	"/ libJpeg can only handle real OS-streams
 
-        tmpFile := Filename newTemporary.
-        [
-            s := tmpFile writeStream binary.
-            s nextPutAll:aStream contents.
-            s close.
-            s := tmpFile readStream binary.
-            ^ self fromStream:s.
-        ] valueNowOrOnUnwindDo:[
-            s notNil ifTrue:[s close].
-            tmpFile destroy.
-        ].
+	tmpFile := Filename newTemporary.
+	[
+	    s := tmpFile writeStream binary.
+	    s nextPutAll:aStream contents.
+	    s close.
+	    s := tmpFile readStream binary.
+	    ^ self fromStream:s.
+	] valueNowOrOnUnwindDo:[
+	    s notNil ifTrue:[s close].
+	    tmpFile destroy.
+	].
         
-        "/ 'JPEGReader [info]: can only read from real streams' infoPrintCR.
-        "/ ^ nil
+	"/ 'JPEGReader [info]: can only read from real streams' infoPrintCR.
+	"/ ^ nil
     ].
 
     inStream := aStream.
@@ -469,27 +503,27 @@
 
     (self create_jpeg_decompress_struct not
     or:[self start_decompress not]) ifTrue:[
-        ok := false.
+	ok := false.
 
-        "/ if there was no SOI marker,
-        "/ try again, skipping first 128 bytes
-        "/ (seems to be generated by some jpg writers)
+	"/ if there was no SOI marker,
+	"/ try again, skipping first 128 bytes
+	"/ (seems to be generated by some jpg writers)
 
-        inStream position:pos1.
-        ((inStream nextByte ~~ 16rFF)
-        or:[inStream nextByte ~~ 16rD8]) ifTrue:[
-            inStream position:pos1 + 128.
-            ((inStream nextByte == 16rFF)
-            and:[inStream nextByte == 16rD8]) ifTrue:[
-                inStream position:pos1 + 128.
-                ok := self create_jpeg_decompress_struct
-                      and:[self start_decompress]
-            ].
-        ].
-        ok ifFalse:[
-            'JPEGReader [info]: ' infoPrint. self get_error_message infoPrintCR.
-            ^ nil
-        ]
+	inStream position:pos1.
+	((inStream nextByte ~~ 16rFF)
+	or:[inStream nextByte ~~ 16rD8]) ifTrue:[
+	    inStream position:pos1 + 128.
+	    ((inStream nextByte == 16rFF)
+	    and:[inStream nextByte == 16rD8]) ifTrue:[
+		inStream position:pos1 + 128.
+		ok := self create_jpeg_decompress_struct
+		      and:[self start_decompress]
+	    ].
+	].
+	ok ifFalse:[
+	    'JPEGReader [info]: ' infoPrint. self get_error_message infoPrintCR.
+	    ^ nil
+	]
     ].
 
     data := ByteArray uninitializedNew:(width * height * colorComponents).
@@ -497,27 +531,27 @@
     bytesPerRow := colorComponents * width.
 
     [(returnCode := self decompressChunkInto:data startingAt:dataIdx) > 0] whileTrue:[
-        "/ got a row in the buffer ...
-        dataIdx := dataIdx + bytesPerRow
+	"/ got a row in the buffer ...
+	dataIdx := dataIdx + bytesPerRow
     ].    
     returnCode < 0 ifTrue:[
-        'JPEGReader [info]: ' infoPrint. self get_error_message infoPrintCR.
-        ^ nil
+	'JPEGReader [info]: ' infoPrint. self get_error_message infoPrintCR.
+	^ nil
     ].
 
     (self finish_decompress) ifFalse:[
-        'JPEGReader [info]: ' infoPrint. self get_error_message infoPrintCR.
-        ^ nil
+	'JPEGReader [info]: ' infoPrint. self get_error_message infoPrintCR.
+	^ nil
     ].
 
     colorComponents == 3 ifTrue:[
-        photometric := #rgb.
-        samplesPerPixel := 3.
-        bitsPerSample := #(8 8 8).
+	photometric := #rgb.
+	samplesPerPixel := 3.
+	bitsPerSample := #(8 8 8).
     ] ifFalse:[
-        photometric := #blackIs0.
-        samplesPerPixel := 1.
-        bitsPerSample := #(8).
+	photometric := #blackIs0.
+	samplesPerPixel := 1.
+	bitsPerSample := #(8).
     ].
 
     "
@@ -540,6 +574,6 @@
 !JPEGReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/JPEGReader.st,v 1.34 1998-05-28 14:50:07 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/JPEGReader.st,v 1.35 1998-09-08 10:10:47 cg Exp $'
 ! !
 JPEGReader initialize!