[commit][3744] CogVM source as per VMMaker.oscog-eem.1887

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[commit][3744] CogVM source as per VMMaker.oscog-eem.1887

commits-3
 
Revision: 3744
Author:   eliot
Date:     2016-06-09 17:08:28 -0700 (Thu, 09 Jun 2016)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1887

Integrate Laura's greyscale JPEG support code.
Requires http://squeakvm.org/svn/squeak/trunk/platforms/Cross/plugins r3742.

Modified Paths:
--------------
    branches/Cog/src/plugins/JPEGReadWriter2Plugin/JPEGReadWriter2Plugin.c

Property Changed:
----------------
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Wed Jun  8 11:19:12 PDT 2016
   + Thu Jun  9 17:07:14 PDT 2016

Modified: branches/Cog/src/plugins/JPEGReadWriter2Plugin/JPEGReadWriter2Plugin.c
===================================================================
--- branches/Cog/src/plugins/JPEGReadWriter2Plugin/JPEGReadWriter2Plugin.c 2016-06-10 00:05:42 UTC (rev 3743)
+++ branches/Cog/src/plugins/JPEGReadWriter2Plugin/JPEGReadWriter2Plugin.c 2016-06-10 00:08:28 UTC (rev 3744)
@@ -1,9 +1,9 @@
 /* Automatically generated by
- SmartSyntaxPluginCodeGenerator VMMaker.oscog-eem.1716 uuid: 9115c93b-f425-4118-96e7-7130adeff1f2
+ SmartSyntaxPluginCodeGenerator VMMaker.oscog-eem.1887 uuid: 39e48685-63a6-498b-b4c5-8e7aa0c162dd
    from
- JPEGReadWriter2Plugin VMMaker.oscog-eem.1716 uuid: 9115c93b-f425-4118-96e7-7130adeff1f2
+ JPEGReadWriter2Plugin VMMaker.oscog-eem.1887 uuid: 39e48685-63a6-498b-b4c5-8e7aa0c162dd
  */
-static char __buildInfo[] = "JPEGReadWriter2Plugin VMMaker.oscog-eem.1716 uuid: 9115c93b-f425-4118-96e7-7130adeff1f2 " __DATE__ ;
+static char __buildInfo[] = "JPEGReadWriter2Plugin VMMaker.oscog-eem.1887 uuid: 39e48685-63a6-498b-b4c5-8e7aa0c162dd " __DATE__ ;
 
 
 
@@ -37,6 +37,7 @@
 EXPORT(const char*) getModuleName(void);
 EXPORT(sqInt) initialiseModule(void);
 EXPORT(sqInt) primImageHeight(void);
+EXPORT(sqInt) primImageNumComponents(void);
 EXPORT(sqInt) primImageWidth(void);
 EXPORT(sqInt) primJPEGCompressStructSize(void);
 EXPORT(sqInt) primJPEGDecompressStructSize(void);
@@ -45,6 +46,7 @@
 EXPORT(sqInt) primJPEGReadHeaderfromByteArrayerrorMgr(void);
 EXPORT(sqInt) primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgr(void);
 EXPORT(sqInt) primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgr(void);
+EXPORT(sqInt) primSupports8BitGrayscaleJPEGs(void);
 EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
 EXPORT(sqInt) shutdownModule(void);
 static sqInt sqAssert(sqInt aBool);
@@ -66,6 +68,7 @@
 static sqInt (*isWordsOrBytes)(sqInt oop);
 static sqInt (*pop)(sqInt nItems);
 static sqInt (*popthenPush)(sqInt nItems, sqInt oop);
+static sqInt (*stSizeOf)(sqInt oop);
 static sqInt (*stackIntegerValue)(sqInt offset);
 static sqInt (*stackValue)(sqInt offset);
 static sqInt (*success)(sqInt aBoolean);
@@ -84,6 +87,7 @@
 extern sqInt isWordsOrBytes(sqInt oop);
 extern sqInt pop(sqInt nItems);
 extern sqInt popthenPush(sqInt nItems, sqInt oop);
+extern sqInt stSizeOf(sqInt oop);
 extern sqInt stackIntegerValue(sqInt offset);
 extern sqInt stackValue(sqInt offset);
 extern sqInt success(sqInt aBoolean);
@@ -93,9 +97,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
- "JPEGReadWriter2Plugin VMMaker.oscog-eem.1716 (i)"
+ "JPEGReadWriter2Plugin VMMaker.oscog-eem.1887 (i)"
 #else
- "JPEGReadWriter2Plugin VMMaker.oscog-eem.1716 (e)"
+ "JPEGReadWriter2Plugin VMMaker.oscog-eem.1887 (e)"
 #endif
 ;
 
@@ -148,6 +152,34 @@
  return null;
 }
 
+ /* JPEGReadWriter2Plugin>>#primImageNumComponents: */
+EXPORT(sqInt)
+primImageNumComponents(void)
+{
+ char *aJPEGDecompressStruct;
+ sqInt _return_value;
+
+ success(isBytes(stackValue(0)));
+ aJPEGDecompressStruct = ((char *) (firstIndexableField(stackValue(0))));
+ if (failed()) {
+ return null;
+ }
+
+ interpreterProxy->success
+ ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(0))) >= (sizeof(struct jpeg_decompress_struct)));
+ if (interpreterProxy->failed()) return null;
+
+ if (failed()) {
+ return null;
+ }
+ _return_value = integerObjectOf((((j_decompress_ptr)aJPEGDecompressStruct)->num_components));
+ if (failed()) {
+ return null;
+ }
+ popthenPush(2, _return_value);
+ return null;
+}
+
  /* JPEGReadWriter2Plugin>>#primImageWidth: */
 EXPORT(sqInt)
 primImageWidth(void)
@@ -250,8 +282,6 @@
 {
  char *aJPEGDecompressStruct;
  char *aJPEGErrorMgr2Struct;
- j_decompress_ptr  pcinfo;
- error_ptr2  pjerr;
  char *source;
  sqInt sourceSize;
 
@@ -264,37 +294,18 @@
  if (failed()) {
  return null;
  }
- pcinfo = null;
- pjerr = null;
- sourceSize = null;
-
- interpreterProxy->success
- ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(2))) >= (sizeof(struct jpeg_decompress_struct)));
- interpreterProxy->success
- ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(0))) >= (sizeof(struct error_mgr2)));
- if (interpreterProxy->failed()) return null;
-
-
- sourceSize = interpreterProxy->stSizeOf(interpreterProxy->stackValue(1));
- pcinfo = (j_decompress_ptr)aJPEGDecompressStruct;
- pjerr = (error_ptr2)aJPEGErrorMgr2Struct;
- if (sourceSize) {
- pcinfo->err = jpeg_std_error(&pjerr->pub);
- pjerr->pub.error_exit = error_exit;
- if (setjmp(pjerr->setjmp_buffer)) {
- jpeg_destroy_decompress(pcinfo);
- sourceSize = 0;
- }
- if (sourceSize) {
- jpeg_create_decompress(pcinfo);
- jpeg_mem_src(pcinfo, source, sourceSize);
- jpeg_read_header(pcinfo, TRUE);
- }
- }
-
+ success(interpreterProxy->stSizeOf(interpreterProxy->stackValue(2)) >= (sizeof(struct jpeg_decompress_struct)));
+ success(interpreterProxy->stSizeOf(interpreterProxy->stackValue(0)) >= (sizeof(struct error_mgr2)));
  if (failed()) {
  return null;
  }
+ sourceSize = stSizeOf(stackValue(1));
+ if (sourceSize > 0) {
+ primJPEGReadHeaderfromByteArraysizeerrorMgrReadHeader(aJPEGDecompressStruct, source, sourceSize, aJPEGErrorMgr2Struct);
+ }
+ if (failed()) {
+ return null;
+ }
  pop(3);
  return null;
 }
@@ -305,43 +316,22 @@
 {
  char *aJPEGDecompressStruct;
  char *aJPEGErrorMgr2Struct;
- sqInt b1;
- sqInt b2;
- sqInt bOff;
- sqInt bOff2;
- JSAMPARRAY  buffer;
- sqInt di;
  sqInt ditherFlag;
- sqInt dmi;
- sqInt dmo;
- sqInt dmv1;
- sqInt dmv2;
  sqInt form;
- unsigned *  formBits;
- sqInt formBitsOops;
- sqInt formBitsSize;
+ unsigned int*formBitmap;
+ sqInt formBitmapOOP;
+ sqInt formBitmapSizeInBytes;
+ int formComponentBitSize;
+ int formComponents;
  sqInt formDepth;
  sqInt formHeight;
+ sqInt formNativeDepth;
  sqInt formPitch;
- sqInt formPix;
  sqInt formWidth;
- sqInt g1;
- sqInt g2;
- sqInt gOff;
- sqInt gOff2;
- sqInt i;
- sqInt j;
- sqInt ok;
- j_decompress_ptr  pcinfo;
- sqInt pixPerWord;
- error_ptr2  pjerr;
- sqInt r1;
- sqInt r2;
- sqInt rOff;
- sqInt rOff2;
- sqInt rowStride;
+ int pixelsPerWord;
  char *source;
  sqInt sourceSize;
+ sqInt wordsPerRow;
 
  success(isBytes(stackValue(4)));
  aJPEGDecompressStruct = ((char *) (firstIndexableField(stackValue(4))));
@@ -355,165 +345,52 @@
  if (failed()) {
  return null;
  }
- pcinfo = null;
- pjerr = null;
- buffer = null;
- rowStride = null;
- formDepth = null;
- formBits = null;
- i = null;
- j = null;
- formPix = null;
- ok = null;
- rOff = null;
- gOff = null;
- bOff = null;
- rOff2 = null;
- gOff2 = null;
- bOff2 = null;
- sourceSize = null;
- r1 = null;
- r2 = null;
- g1 = null;
- g2 = null;
- b1 = null;
- b2 = null;
- dmv1 = null;
- dmv2 = null;
- di = null;
- dmi = null;
- dmo = null;
- formBitsOops = fetchPointerofObject(0, form);
+ formBitmapOOP = fetchPointerofObject(0, form);
+ formNativeDepth = fetchIntegerofObject(3, form);
+ formWidth = fetchIntegerofObject(1, form);
+ formHeight = fetchIntegerofObject(2, form);
 
  /* Various parameter checks */
- formDepth = fetchIntegerofObject(3, form);
-
- interpreterProxy->success
- ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(4))) >= (sizeof(struct jpeg_decompress_struct)));
- interpreterProxy->success
- ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(0))) >= (sizeof(struct error_mgr2)));
- if (interpreterProxy->failed()) return null;
-
- formWidth = ((j_decompress_ptr)aJPEGDecompressStruct)->image_width;
- formHeight = ((j_decompress_ptr)aJPEGDecompressStruct)->image_height;
- pixPerWord = 32 / formDepth;
- formPitch = ((formWidth + (pixPerWord - 1)) / pixPerWord) * 4;
- formBitsSize = byteSizeOf(formBitsOops);
- success((isWordsOrBytes(formBitsOops))
- && (formBitsSize == (formPitch * formHeight)));
+ formDepth = SQABS(formNativeDepth);
+ success(interpreterProxy->stSizeOf(interpreterProxy->stackValue(4)) >= (sizeof(struct jpeg_decompress_struct)));
+ success(interpreterProxy->stSizeOf(interpreterProxy->stackValue(0)) >= (sizeof(struct error_mgr2)));
  if (failed()) {
  return null;
  }
- formBits = firstIndexableField(formBitsOops);
-
- sourceSize = interpreterProxy->stSizeOf(interpreterProxy->stackValue(3));
- if (sourceSize == 0) {
- interpreterProxy->success(false);
- return null;
- }
- pcinfo = (j_decompress_ptr)aJPEGDecompressStruct;
- pjerr = (error_ptr2)aJPEGErrorMgr2Struct;
- pcinfo->err = jpeg_std_error(&pjerr->pub);
- pjerr->pub.error_exit = error_exit;
- ok = 1;
- if (setjmp(pjerr->setjmp_buffer)) {
- jpeg_destroy_decompress(pcinfo);
- ok = 0;
- }
- if (ok) {
- ok = jpeg_mem_src_newLocationOfData(pcinfo, source, sourceSize);
- if (ok) {
- /* Dither Matrix taken from Form>>orderedDither32To16, but rewritten for this method. */
- int ditherMatrix1[] = { 2, 0, 14, 12, 1, 3, 13, 15 };
- int ditherMatrix2[] = { 10, 8, 6, 4, 9, 11, 5, 7 };
- jpeg_start_decompress(pcinfo);
- rowStride = pcinfo->output_width * pcinfo->output_components;
- if (pcinfo->out_color_components == 3) {
- rOff = 0; gOff = 1; bOff = 2;
- rOff2 = 3; gOff2 = 4; bOff2 = 5;
- } else {
- rOff = 0; gOff = 0; bOff = 0;
- rOff2 = 1; gOff2 = 1; bOff2 = 1;
- }
- /* Make a one-row-high sample array that will go away when done with image */
- buffer = (*(pcinfo->mem)->alloc_sarray)
- ((j_common_ptr) pcinfo, JPOOL_IMAGE, rowStride, 1);
-
- /* Step 6: while (scan lines remain to be read) */
- /*           jpeg_read_scanlines(...); */
-
- /* Here we use the library state variable cinfo.output_scanline as the
- * loop counter, so that we dont have to keep track ourselves.
- */
- while (pcinfo->output_scanline < pcinfo->output_height) {
- /* jpeg_read_scanlines expects an array of pointers to scanlines.
- * Here the array is only one element long, but you could ask for
- * more than one scanline at a time if thats more convenient.
- */
- (void) jpeg_read_scanlines(pcinfo, buffer, 1);
-
- switch (formDepth) {
- case 32:
- for(i = 0, j = 0; i < rowStride; i +=(pcinfo->out_color_components), j++) {
- formPix = (255 << 24) | (buffer[0][i+rOff] << 16) | (buffer[0][i+gOff] << 8) | buffer[0][i+bOff];
- if (formPix == 0) formPix = 1;
- formBits [ ((pcinfo->output_scanline - 1) * (pcinfo->image_width)) + j ] = formPix;
- }
- break;
-
- case 16:
- for(i = 0, j = 0; i < rowStride; i +=(pcinfo->out_color_components*2), j++) {
- r1 = buffer[0][i+rOff];
- r2 = buffer[0][i+rOff2];
- g1 = buffer[0][i+gOff];
- g2 = buffer[0][i+gOff2];
- b1 = buffer[0][i+bOff];
- b2 = buffer[0][i+bOff2];
-
- if (!ditherFlag) {
- r1 = r1 >> 3;
- r2 = r2 >> 3;
- g1 = g1 >> 3;
- g2 = g2 >> 3;
- b1 = b1 >> 3;
- b2 = b2 >> 3;
- } else {
- /* Do 4x4 ordered dithering. Taken from Form>>orderedDither32To16 */
- dmv1 = ditherMatrix1[ ((pcinfo->output_scanline & 3 )<< 1) | (j&1) ];
- dmv2 = ditherMatrix2[ ((pcinfo->output_scanline & 3 )<< 1) | (j&1) ];
-
- di = (r1 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
- if(dmv1 < dmi) { r1 = dmo+1; } else { r1 = dmo; };
- di = (g1 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
- if(dmv1 < dmi) { g1 = dmo+1; } else { g1 = dmo; };
- di = (b1 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
- if(dmv1 < dmi) { b1 = dmo+1; } else { b1 = dmo; };
-
- di = (r2 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
- if(dmv2 < dmi) { r2 = dmo+1; } else { r2 = dmo; };
- di = (g2 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
- if(dmv2 < dmi) { g2 = dmo+1; } else { g2 = dmo; };
- di = (b2 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
- if(dmv2 < dmi) { b2 = dmo+1; } else { b2 = dmo; };
- }
-
- formPix = (r1 << 10) | (g1 << 5) | b1;
- if (!formPix) formPix = 1;
- formPix = (formPix << 16) | (r2 << 10) | (g2 << 5) | b2;
- if (!(formPix & 65535)) formPix = formPix | 1;
- formBits [ ((pcinfo->output_scanline - 1) * (pcinfo->image_width)) / 2 + j ] = formPix;
- }
- break;
- }
- }
- jpeg_finish_decompress(pcinfo);
- }
- jpeg_destroy_decompress(pcinfo);
- }
-
+ formComponents = (formDepth != 8
+ ? 4
+ : 1);
+ formComponentBitSize = (formDepth != 16
+ ? 8
+ : 4);
+ pixelsPerWord = 32 / (formComponents * formComponentBitSize);
+ wordsPerRow = ((formWidth + pixelsPerWord) - 1) / pixelsPerWord;
+ formPitch = ((formWidth + (pixelsPerWord - 1)) / pixelsPerWord) * 4;
+ formBitmapSizeInBytes = byteSizeOf(formBitmapOOP);
+ success((isWordsOrBytes(formBitmapOOP))
+ && (formBitmapSizeInBytes == (formPitch * formHeight)));
  if (failed()) {
  return null;
  }
+ sourceSize = stSizeOf(stackValue(3));
+ success(sourceSize != 0);
+ if (failed()) {
+ return null;
+ }
+ formBitmap = firstIndexableField(formBitmapOOP);
+ primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgrReadScanlines(
+ aJPEGDecompressStruct,
+     aJPEGErrorMgr2Struct,
+ source,
+     sourceSize,
+     ditherFlag,
+     formBitmap,
+   pixelsPerWord,
+   wordsPerRow,
+     formNativeDepth);
+ if (failed()) {
+ return null;
+ }
  pop(5);
  return null;
 }
@@ -524,26 +401,23 @@
 {
  char *aJPEGCompressStruct;
  char *aJPEGErrorMgr2Struct;
- JSAMPARRAY  buffer;
  char *destination;
  unsigned int destinationSize;
  sqInt form;
- unsigned *  formBits;
- sqInt formBitsOops;
- sqInt formBitsSize;
+ unsigned int *formBitmap;
+ sqInt formBitmapOOP;
+ sqInt formBitmapSizeInBytes;
+ int formComponentBitSize;
+ int formComponents;
  sqInt formDepth;
  sqInt formHeight;
+ sqInt formNativeDepth;
  sqInt formPitch;
- sqInt formPix;
  sqInt formWidth;
- sqInt i;
- sqInt j;
- j_compress_ptr  pcinfo;
- sqInt pixPerWord;
- error_ptr2  pjerr;
+ int pixelsPerWord;
  sqInt progressiveFlag;
  sqInt quality;
- sqInt rowStride;
+ sqInt wordsPerRow;
  sqInt _return_value;
 
  success(isBytes(stackValue(5)));
@@ -559,104 +433,53 @@
  if (failed()) {
  return null;
  }
- pcinfo = null;
- pjerr = null;
- buffer = null;
- rowStride = null;
- formBits = null;
- formWidth = null;
- formHeight = null;
- formDepth = null;
- i = null;
- j = null;
- formPix = null;
- destinationSize = null;
- formBitsOops = fetchPointerofObject(0, form);
+ formBitmapOOP = fetchPointerofObject(0, form);
  formWidth = fetchIntegerofObject(1, form);
  formHeight = fetchIntegerofObject(2, form);
+ formNativeDepth = fetchIntegerofObject(3, form);
 
  /* Various parameter checks */
- formDepth = fetchIntegerofObject(3, form);
-
- interpreterProxy->success
- ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(5))) >= (sizeof(struct jpeg_compress_struct)));
- interpreterProxy->success
- ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(0))) >= (sizeof(struct error_mgr2)));
- if (interpreterProxy->failed()) return null;
-
- pixPerWord = 32 / formDepth;
- formPitch = ((formWidth + (pixPerWord - 1)) / pixPerWord) * 4;
- formBitsSize = byteSizeOf(formBitsOops);
- success((isWordsOrBytes(formBitsOops))
- && (formBitsSize == (formPitch * formHeight)));
+ formDepth = SQABS(formNativeDepth);
+ success(interpreterProxy->stSizeOf(interpreterProxy->stackValue(5)) >= (sizeof(struct jpeg_compress_struct)));
+ success(interpreterProxy->stSizeOf(interpreterProxy->stackValue(0)) >= (sizeof(struct error_mgr2)));
  if (failed()) {
  return null;
  }
- formBits = firstIndexableField(formBitsOops);
-
- destinationSize = interpreterProxy->stSizeOf(interpreterProxy->stackValue(4));
- pcinfo = (j_compress_ptr)aJPEGCompressStruct;
- pjerr = (error_ptr2)aJPEGErrorMgr2Struct;
- if (destinationSize) {
- pcinfo->err = jpeg_std_error(&pjerr->pub);
- pjerr->pub.error_exit = error_exit;
- if (setjmp(pjerr->setjmp_buffer)) {
- jpeg_destroy_compress(pcinfo);
- destinationSize = 0;
- }
- if (destinationSize) {
- jpeg_create_compress(pcinfo);
- jpeg_mem_dest(pcinfo, destination, &destinationSize);
- pcinfo->image_width = formWidth;
- pcinfo->image_height = formHeight;
- pcinfo->input_components = 3;
- pcinfo->in_color_space = JCS_RGB;
- jpeg_set_defaults(pcinfo);
- if (quality > 0)
- jpeg_set_quality (pcinfo, quality, 1);
- if (progressiveFlag)
- jpeg_simple_progression(pcinfo);
- jpeg_start_compress(pcinfo, TRUE);
- rowStride = formWidth * 3;
-
- /* Make a one-row-high sample array that will go away
-  when done with image */
- buffer = (*(pcinfo->mem)->alloc_sarray)
- ((j_common_ptr) pcinfo, JPOOL_IMAGE, rowStride, 1);
-
- while (pcinfo->next_scanline < pcinfo->image_height) {
- switch (formDepth) {
- case 32:
- for(i = 0, j = 0; i < rowStride; i +=3, j++) {
- formPix = formBits [ ((pcinfo->next_scanline) * formWidth) + j ];
- buffer[0][i] = (formPix >> 16) & 255;
- buffer[0][i+1] = (formPix >> 8) & 255;
- buffer[0][i+2] = formPix & 255;
- }
- break;
- case 16:
- for(i = 0, j = 0; i < rowStride; i +=6, j++) {
- formPix = formBits [ ((pcinfo->next_scanline) * formWidth) / 2 + j ];
- buffer[0][i] = (formPix >> 23) & 248;
- buffer[0][i+1] = (formPix >> 18) & 248;
- buffer[0][i+2] = (formPix >> 13) & 248;
- buffer[0][i+3] = (formPix >> 7) & 248;
- buffer[0][i+4] = (formPix >> 2) & 248;
- buffer[0][i+5] = (formPix << 3) & 248;
- }
- break;
- }
- (void) jpeg_write_scanlines(pcinfo, buffer, 1);
-
- }
- jpeg_finish_compress(pcinfo);
- jpeg_destroy_compress(pcinfo);
- }
- }
-
+ formComponents = (formDepth != 8
+ ? 4
+ : 1);
+ formComponentBitSize = (formDepth != 16
+ ? 8
+ : 4);
+ pixelsPerWord = 32 / (formComponents * formComponentBitSize);
+ wordsPerRow = ((formWidth + pixelsPerWord) - 1) / pixelsPerWord;
+ formPitch = wordsPerRow * 4;
+ formBitmapSizeInBytes = byteSizeOf(formBitmapOOP);
+ success((isWordsOrBytes(formBitmapOOP))
+ && (formBitmapSizeInBytes == (formPitch * formHeight)));
  if (failed()) {
  return null;
  }
+ formBitmap = firstIndexableField(formBitmapOOP);
+ destinationSize = stSizeOf(stackValue(4));
+ if (!(destinationSize == 0)) {
+ primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgrWriteScanlines(
+ formWidth,
+ formHeight,
+ formNativeDepth,
+ formBitmap,
+ aJPEGCompressStruct,
+ aJPEGErrorMgr2Struct,
+ quality,
+ progressiveFlag,
+ pixelsPerWord,
+ wordsPerRow,
+ destination,
+ &destinationSize);
+ }
+ if (failed()) {
+ return null;
+ }
  _return_value = integerObjectOf((destinationSize));
  if (failed()) {
  return null;
@@ -665,7 +488,24 @@
  return null;
 }
 
+ /* JPEGReadWriter2Plugin>>#primSupports8BitGrayscaleJPEGs */
+EXPORT(sqInt)
+primSupports8BitGrayscaleJPEGs(void)
+{
+ sqInt _return_value;
 
+ if (failed()) {
+ return null;
+ }
+ _return_value = ((1) ? trueObject() : falseObject());
+ if (failed()) {
+ return null;
+ }
+ popthenPush(1, _return_value);
+ return null;
+}
+
+
 /* Note: This is coded so that it can be run in Squeak. */
 
  /* InterpreterPlugin>>#setInterpreter: */
@@ -693,6 +533,7 @@
  isWordsOrBytes = interpreterProxy->isWordsOrBytes;
  pop = interpreterProxy->pop;
  popthenPush = interpreterProxy->popthenPush;
+ stSizeOf = interpreterProxy->stSizeOf;
  stackIntegerValue = interpreterProxy->stackIntegerValue;
  stackValue = interpreterProxy->stackValue;
  success = interpreterProxy->success;
@@ -725,6 +566,7 @@
  {(void*)_m, "getModuleName", (void*)getModuleName},
  {(void*)_m, "initialiseModule", (void*)initialiseModule},
  {(void*)_m, "primImageHeight\000\377", (void*)primImageHeight},
+ {(void*)_m, "primImageNumComponents\000\377", (void*)primImageNumComponents},
  {(void*)_m, "primImageWidth\000\377", (void*)primImageWidth},
  {(void*)_m, "primJPEGCompressStructSize\000\377", (void*)primJPEGCompressStructSize},
  {(void*)_m, "primJPEGDecompressStructSize\000\377", (void*)primJPEGDecompressStructSize},
@@ -733,6 +575,7 @@
  {(void*)_m, "primJPEGReadHeaderfromByteArrayerrorMgr\000\377", (void*)primJPEGReadHeaderfromByteArrayerrorMgr},
  {(void*)_m, "primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgr\000\002", (void*)primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgr},
  {(void*)_m, "primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgr\000\002", (void*)primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgr},
+ {(void*)_m, "primSupports8BitGrayscaleJPEGs\000\377", (void*)primSupports8BitGrayscaleJPEGs},
  {(void*)_m, "setInterpreter", (void*)setInterpreter},
  {(void*)_m, "shutdownModule\000\377", (void*)shutdownModule},
  {NULL, NULL, NULL}