[commit][3741] Integrate Laura Perez Carrato' s 8- & 16-bit JPEG enhancement support code.

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

[commit][3741] Integrate Laura Perez Carrato' s 8- & 16-bit JPEG enhancement support code.

commits-3
 
Revision: 3741
Author:   eliot
Date:     2016-06-09 16:07:42 -0700 (Thu, 09 Jun 2016)
Log Message:
-----------
Integrate Laura Perez Carrato's 8- & 16-bit JPEG enhancement support code.

Added Paths:
-----------
    trunk/platforms/Cross/plugins/JPEGReadWriter2Plugin/sqJPEGReadWriter2Plugin.c

Property Changed:
----------------
    trunk/platforms/Cross/plugins/sqPluginsSCCSVersion.h

Added: trunk/platforms/Cross/plugins/JPEGReadWriter2Plugin/sqJPEGReadWriter2Plugin.c
===================================================================
--- trunk/platforms/Cross/plugins/JPEGReadWriter2Plugin/sqJPEGReadWriter2Plugin.c                        (rev 0)
+++ trunk/platforms/Cross/plugins/JPEGReadWriter2Plugin/sqJPEGReadWriter2Plugin.c 2016-06-09 23:07:42 UTC (rev 3741)
@@ -0,0 +1,307 @@
+/* sqJPEGReadWriter2Plugin.c
+ * Cross-platform interface to JPEG processing.
+ *
+ * Author: Laura Perez Carrato
+ *
+ * Copyright (c) 2013 3D Immersive Collaboration Consulting, LLC.
+ *
+ * All rights reserved.
+ *  
+ *   This file is part of Squeak.
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining a
+ *   copy of this software and associated documentation files (the "Software"),
+ *   to deal in the Software without restriction, including without limitation
+ *   the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *   and/or sell copies of the Software, and to permit persons to whom the
+ *   Software is furnished to do so, subject to the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be included in
+ *   all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ *   DEALINGS IN THE SOFTWARE.
+ */
+#include "JPEGReadWriter2Plugin.h"
+
+/*
+ * For more info regarding what's being done here, download libjpeg 6b from
+ * http://www.ijg.org/files/ and take a look at example.c
+ */
+
+void
+primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgrWriteScanlines(
+    unsigned int width,
+    unsigned int height,
+    int nativeDepth,
+    unsigned int* bitmap,
+    char* jpegCompressStruct,
+    char* jpegErrorMgr2Struct,
+    int quality,
+    int progressiveFlag,
+    unsigned int pixelsPerWord,
+    unsigned int wordsPerRow,
+    char* destination,
+    unsigned int* destinationSizePtr)
+{
+    j_compress_ptr pcinfo = (j_compress_ptr)jpegCompressStruct;
+ error_ptr2 pjerr = (error_ptr2)jpegErrorMgr2Struct;
+
+ pcinfo->err = jpeg_std_error(&pjerr->pub);
+ pjerr->pub.error_exit = error_exit;
+
+ if (setjmp(pjerr->setjmp_buffer)) {
+ jpeg_destroy_compress(pcinfo);
+
+ *destinationSizePtr = 0;
+ }
+
+ if (*destinationSizePtr) {
+ jpeg_create_compress(pcinfo);
+ jpeg_mem_dest(pcinfo, destination, destinationSizePtr);
+
+ pcinfo->image_width = width;
+ pcinfo->image_height = height;
+ pcinfo->input_components = (abs(nativeDepth) != 8 ? 3 : 1);
+ pcinfo->in_color_space = (abs(nativeDepth) != 8 ? JCS_RGB : JCS_GRAYSCALE);
+ jpeg_set_defaults(pcinfo);
+ if (quality > 0)
+ jpeg_set_quality (pcinfo, quality, 1);
+ if (progressiveFlag)
+ jpeg_simple_progression(pcinfo);
+
+ jpeg_start_compress(pcinfo, TRUE);
+
+ unsigned int rowStride = wordsPerRow * pixelsPerWord * pcinfo->input_components;
+
+ JSAMPARRAY buffer = (*(pcinfo->mem)->alloc_sarray)
+ ((j_common_ptr) pcinfo, JPOOL_IMAGE, rowStride, 1);
+
+ while (pcinfo->next_scanline < pcinfo->image_height) {
+    unsigned int i;
+    unsigned int j;
+ for(i = 0, j = 0; i < rowStride; i +=(pcinfo->input_components * pixelsPerWord), j++) {
+ unsigned int bitmapWord = bitmap[pcinfo->next_scanline * wordsPerRow + j];
+
+ switch (nativeDepth) {
+ case 32:
+ case -32:
+ buffer[0][i] = (bitmapWord >> 16) & 255;
+ buffer[0][i+1] = (bitmapWord >> 8) & 255;
+ buffer[0][i+2] = bitmapWord & 255;
+ break;
+ case 16:
+ buffer[0][i] = (bitmapWord >> 23) & 248;
+ buffer[0][i+1] = (bitmapWord >> 18) & 248;
+ buffer[0][i+2] = (bitmapWord >> 13) & 248;
+ buffer[0][i+3] = (bitmapWord >> 7) & 248;
+ buffer[0][i+4] = (bitmapWord >> 2) & 248;
+ buffer[0][i+5] = (bitmapWord << 3) & 248;
+ break;
+ case -16:
+ buffer[0][i] = (bitmapWord >> 7) & 248;
+ buffer[0][i+1] = (bitmapWord >> 2) & 248;
+ buffer[0][i+2] = (bitmapWord << 3) & 248;
+ buffer[0][i+3] = (bitmapWord >> 23) & 248;
+ buffer[0][i+4] = (bitmapWord >> 18) & 248;
+ buffer[0][i+5] = (bitmapWord >> 13) & 248;
+ break;
+ case 8:
+ buffer[0][i] = (bitmapWord >> 24) & 255;
+ buffer[0][i+1] = (bitmapWord >> 16) & 255;
+ buffer[0][i+2] = (bitmapWord >> 8) & 255;
+ buffer[0][i+3] = bitmapWord & 255;
+ break;
+ case -8:
+ buffer[0][i] = bitmapWord & 255;
+ buffer[0][i+1] = (bitmapWord >> 8) & 255;
+ buffer[0][i+2] = (bitmapWord >> 16) & 255;
+ buffer[0][i+3] = (bitmapWord >> 24) & 255;
+ break;
+ }
+ }
+
+ (void) jpeg_write_scanlines(pcinfo, buffer, 1);
+ }
+
+ jpeg_finish_compress(pcinfo);
+ jpeg_destroy_compress(pcinfo);
+ }
+}
+
+void
+primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgrReadScanlines(
+    char* jpegDecompressStruct,
+    char* jpegErrorMgr2Struct,
+    char* source,
+    unsigned int sourceSize,
+    int ditherFlag,
+    unsigned int* bitmap,
+    unsigned int pixelsPerWord,
+    unsigned int wordsPerRow,
+    int nativeDepth)
+{
+ j_decompress_ptr pcinfo = (j_decompress_ptr)jpegDecompressStruct;
+ error_ptr2 pjerr = (error_ptr2)jpegErrorMgr2Struct;
+
+ int ok = 1;
+ pcinfo->err = jpeg_std_error(&pjerr->pub);
+ pjerr->pub.error_exit = error_exit;
+
+ if (setjmp(pjerr->setjmp_buffer)) {
+ jpeg_destroy_decompress(pcinfo);
+ ok = 0;
+ }
+
+ if (ok)
+ ok = jpeg_mem_src_newLocationOfData(pcinfo, source, sourceSize);
+
+ if (ok) {
+ jpeg_start_decompress(pcinfo);
+
+ int depth = abs(nativeDepth);
+
+ unsigned int rowStride = pcinfo->output_width * pcinfo->output_components;
+
+ JSAMPARRAY buffer = (*(pcinfo->mem)->alloc_sarray)
+ ((j_common_ptr) pcinfo, JPOOL_IMAGE, rowStride, 1);
+
+ int redOffset1, redOffset2;
+ int greenOffset1, greenOffset2;
+ int blueOffset1, blueOffset2;
+
+ if (pcinfo->out_color_components == 3) {
+ redOffset1 = 0; redOffset2 = 3;
+ greenOffset1 = 1; greenOffset2 = 4;
+ blueOffset1 = 2; blueOffset2 = 5;
+ }
+ else {
+ redOffset1 = 0; redOffset2 = 1;
+ greenOffset1 = 0; greenOffset2 = 1;
+ blueOffset1 = 0; blueOffset2 = 1;
+ }
+
+ int grayOffset1 = 0;
+ int grayOffset2 = 1;
+ int grayOffset3 = 2;
+ int grayOffset4 = 3;
+
+ // 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 };
+
+ while (pcinfo->output_scanline < pcinfo->output_height) {
+ (void) jpeg_read_scanlines(pcinfo, buffer, 1);
+
+ unsigned int i;
+ unsigned int j;
+
+ for(i = 0, j = 0; i < rowStride; i +=(pcinfo->out_color_components * pixelsPerWord), j++) {
+ unsigned int bitmapWord;
+
+ switch (depth) {
+ case 32: ;
+ unsigned char red = buffer[0][i+redOffset1];
+ unsigned char green = buffer[0][i+greenOffset1];
+ unsigned char blue = buffer[0][i+blueOffset1];
+ bitmapWord = (255 << 24) | (red << 16) | (green << 8) | blue;
+ break;
+ case 16: ;
+ unsigned char red1 = buffer[0][i+redOffset1];
+ unsigned char red2 = buffer[0][i+redOffset2];
+ unsigned char green1 = buffer[0][i+greenOffset1];
+ unsigned char green2 = buffer[0][i+greenOffset2];
+ unsigned char blue1 = buffer[0][i+blueOffset1];
+ unsigned char blue2 = buffer[0][i+blueOffset2];
+
+ if (ditherFlag) {
+ // Do 4x4 ordered dithering. Taken from Form>>orderedDither32To16
+ int dmv1, dmv2, di, dmi, dmo;
+ dmv1 = ditherMatrix1[((pcinfo->output_scanline & 3) << 1) | (j&1)];
+ dmv2 = ditherMatrix2[((pcinfo->output_scanline & 3) << 1) | (j&1)];
+ di = (red1 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
+ red1 = dmv1 < dmi ? dmo+1 : dmo;
+ di = (green1 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
+ green1 = dmv1 < dmi ? dmo+1 : dmo;
+ di = (blue1 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
+ blue1 = dmv1 < dmi ? dmo+1 : dmo;
+ di = (red2 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
+ red2 = dmv2 < dmi ? dmo+1 : dmo;
+ di = (green2 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
+ green2 = dmv2 < dmi ? dmo+1 : dmo;
+ di = (blue2 * 496) >> 8; dmi = di & 15; dmo = di >> 4;
+ blue2 = dmv2 < dmi ? dmo+1 : dmo;
+ }
+ else {
+ red1 = red1 >> 3;
+ red2 = red2 >> 3;
+ green1 = green1 >> 3;
+ green2 = green2 >> 3;
+ blue1 = blue1 >> 3;
+ blue2 = blue2 >> 3;
+ }
+
+ switch (nativeDepth) {
+ case 16:
+ bitmapWord = 32768 | (red1 << 10) | (green1 << 5) | blue1;
+ bitmapWord = (bitmapWord << 16) | 32768 | (red2 << 10) | (green2 << 5) | blue2;
+ break;
+ case -16:
+ bitmapWord = 32768 | (red2 << 10) | (green2 << 5) | blue2;
+ bitmapWord = (bitmapWord << 16) | 32768 | (red1 << 10) | (green1 << 5) | blue1;
+ break;
+ }
+
+ break;
+ case 8: ;
+ unsigned char gray1 = buffer[0][i+grayOffset1];
+ unsigned char gray2 = buffer[0][i+grayOffset2];
+ unsigned char gray3 = buffer[0][i+grayOffset3];
+ unsigned char gray4 = buffer[0][i+grayOffset4];
+ switch (nativeDepth) {
+ case 8:
+ bitmapWord = gray1 << 24 | gray2 << 16 | gray3 << 8 | gray4;
+ break;
+ case -8:
+ bitmapWord = gray4 << 24 | gray3 << 16 | gray2 << 8 | gray1;
+ break;
+ }
+ break;
+ }
+ bitmap[((pcinfo->output_scanline - 1) * wordsPerRow) + j] = bitmapWord;
+ }
+ }
+ jpeg_finish_decompress(pcinfo);
+ jpeg_destroy_decompress(pcinfo);
+ }
+}
+
+void
+primJPEGReadHeaderfromByteArrayerrorMgrReadHeader (
+    char* jpegDecompressStruct,
+    char* jpegErrorMgr2Struct,
+    char* source,
+    unsigned int sourceSize)
+{
+    j_decompress_ptr pcinfo = (j_decompress_ptr)jpegDecompressStruct;
+ error_ptr2 pjerr = (error_ptr2)jpegErrorMgr2Struct;
+
+ 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);
+ }
+}


Property changes on: trunk/platforms/Cross/plugins/sqPluginsSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Tue May 24 17:24:39 PDT 2016
   + Thu Jun  9 16:06:05 PDT 2016

Reply | Threaded
Open this post in threaded view
|

Re: [commit][3741] Integrate Laura Perez Carrato' s 8- & 16-bit JPEG enhancement support code.

David T. Lewis
 
On Thu, Jun 09, 2016 at 04:07:43PM -0700, [hidden email] wrote:
>  
> Revision: 3741
> Author:   eliot
> Date:     2016-06-09 16:07:42 -0700 (Thu, 09 Jun 2016)
> Log Message:
> -----------
> Integrate Laura Perez Carrato's 8- & 16-bit JPEG enhancement support code.

Yay! Thank you Laura, this is a welcome improvement.

Eliot, brilliant - thanks for pushing this.

One small additional improvement might be to rename the functions in Cross
to follow the naming convention sqSomePlatformFunction() so that they do not
look like auto-generated code. So perhaps
primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgrWriteScanlines()
could be named sqJPEGWriteImageOnByteArray(), and similarly for the other
two functions.

Sorry for not suggesting this earlier, I meant to do so but got distracted.

Dave