[Pkg-javascript-commits] [pdf.js] 09/210: Refactor jpg.js and include forceRGBoutput, correct style of image.js

David Prévot taffit at moszumanska.debian.org
Thu Jun 5 14:20:56 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch upstream
in repository pdf.js.

commit e7fe45a5c455393259d93dc93f1d4c826edc5237
Author: Thorben Bochenek <thorbenb at opera.com>
Date:   Thu Mar 27 11:11:28 2014 +0100

    Refactor jpg.js and include forceRGBoutput, correct style of image.js
    
    This refactors getData to be more readable and extracts all the color
    conversion algorithms to their own functions. The resulting code was then
    cleaned up.
    This also introduces a flag `forceRGBoutput` to getData, that allows to always
    get the data as a `width * height * 3` bytes long RGB buffer
---
 external/jpgjs/jpg.js | 193 ++++++++++++++++++++++++++++----------------------
 src/core/image.js     |  15 +++-
 2 files changed, 121 insertions(+), 87 deletions(-)

diff --git a/external/jpgjs/jpg.js b/external/jpgjs/jpg.js
index 549097b..bd8510a 100644
--- a/external/jpgjs/jpg.js
+++ b/external/jpgjs/jpg.js
@@ -782,9 +782,10 @@ var JpegImage = (function jpegImage() {
           blocksPerColumn: component.blocksPerColumn
         });
       }
+      this.numComponents = this.components.length;
     },
 
-    getData: function getData(width, height) {
+    _getLinearizedBlockData: function getLinearizedBlockData(width, height) {
       var scaleX = this.width / width, scaleY = this.height / height;
 
       var component, componentScaleX, componentScaleY;
@@ -842,80 +843,124 @@ var JpegImage = (function jpegImage() {
           }
         }
       }
+      return data;
+    },
 
-      // ... then transform colors, if necessary
-      switch (numComponents) {
-        case 1: case 2: break;
-        // no color conversion for one or two compoenents
+    _isColorConversionNeeded: function isColorConversionNeeded() {
+      if (this.adobe && this.adobe.transformCode) {
+        // The adobe transform marker overrides any previous setting
+        return true;
+      } else if (this.numComponents == 3) {
+        return true;
+      } else {
+        return false;
+      }
+    },
 
-        case 3:
-          // The default transform for three components is true
-          colorTransform = true;
-          // The adobe transform marker overrides any previous setting
-          if (this.adobe && this.adobe.transformCode)
-            colorTransform = true;
-          else if (typeof this.colorTransform !== 'undefined')
-            colorTransform = !!this.colorTransform;
-
-          if (colorTransform) {
-            for (i = 0; i < dataLength; i += numComponents) {
-              Y  = data[i    ];
-              Cb = data[i + 1];
-              Cr = data[i + 2];
-
-              R = clamp0to255(Y + 1.402 * (Cr - 128));
-              G = clamp0to255(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128));
-              B = clamp0to255(Y + 1.772 * (Cb - 128));
-
-              data[i    ] = R;
-              data[i + 1] = G;
-              data[i + 2] = B;
-            }
-          }
-          break;
-        case 4:
-          // The default transform for four components is false
-          colorTransform = false;
-          // The adobe transform marker overrides any previous setting
-          if (this.adobe && this.adobe.transformCode)
-            colorTransform = true;
-          else if (typeof this.colorTransform !== 'undefined')
-            colorTransform = !!this.colorTransform;
-
-          if (colorTransform) {
-            for (i = 0; i < dataLength; i += numComponents) {
-              Y  = data[i];
-              Cb = data[i + 1];
-              Cr = data[i + 2];
-
-              C = 255 - clamp0to255(Y + 1.402 * (Cr - 128));
-              M = 255 - clamp0to255(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128));
-              Ye = 255 - clamp0to255(Y + 1.772 * (Cb - 128));
-
-              data[i    ] = C;
-              data[i + 1] = M;
-              data[i + 2] = Ye;
-              // K is unchanged
-            }
+    _convertYccToRgb: function convertYccToRgb(data) {
+      var Y, Cb, Cr;
+      for (var i = 0; i < data.length; i += this.numComponents) {
+        Y  = data[i    ];
+        Cb = data[i + 1];
+        Cr = data[i + 2];
+        data[i    ] = clamp0to255(Y + 1.402 * (Cr - 128));
+        data[i + 1] = clamp0to255(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128));
+        data[i + 2] = clamp0to255(Y + 1.772 * (Cb - 128));
+      }
+      return data;
+    },
+
+    _convertYcckToRgb: function convertYcckToRgb(data) {
+      var Y, Cb, Cr, K, C, M, Ye, oneMinusK255th;
+      var outputData = new Uint8Array((data.length / 4) * 3);
+      var offset = 0;
+      for (var i = 0; i < data.length; i += this.numComponents) {
+        Y  = data[i];
+        Cb = data[i + 1];
+        Cr = data[i + 2];
+        K = data[i + 3];
+        C = 255 - clamp0to255(Y + 1.402 * (Cr - 128));
+        M = 255 - clamp0to255(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128));
+        Ye = 255 - clamp0to255(Y + 1.772 * (Cb - 128));
+        oneMinusK255th = (1 - K / 255);
+        outputData[offset++] = 255 - clamp0to255(C * oneMinusK255th + K);
+        outputData[offset++] = 255 - clamp0to255(M * oneMinusK255th + K);
+        outputData[offset++] = 255 - clamp0to255(Ye * oneMinusK255th + K);
+      }
+      return outputData;
+    },
+
+    _convertYcckToCmyk: function convertYcckToCmyk(data) {
+      var Y, Cb, Cr;
+      for (var i = 0; i < data.length; i += this.numComponents) {
+        Y  = data[i];
+        Cb = data[i + 1];
+        Cr = data[i + 2];
+        data[i    ] = 255 - clamp0to255(Y + 1.402 * (Cr - 128));
+        data[i + 1] = 255 - clamp0to255(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128));
+        data[i + 2] = 255 - clamp0to255(Y + 1.772 * (Cb - 128));
+        // K in data[i + 3] is unchanged
+      }
+      return data;
+    },
+
+    _convertCmykToRgb: function convertCmykToRgb(data) {
+      var C, M, Y, K, oneMinusK255th;
+      var outputData = new Uint8Array((data.length / 4) * 3);
+      var offset = 0;
+      for (var i = 0; i < data.length; i += this.numComponents) {
+        C = data[i   ];
+        M = data[i + 1];
+        Y = data[i + 2];
+        K = data[i + 3];
+        oneMinusK255th = (1 - K / 255);
+        outputData[offset++] = 255 - clamp0to255(C * oneMinusK255th + K);
+        outputData[offset++] = 255 - clamp0to255(M * oneMinusK255th + K);
+        outputData[offset++] = 255 - clamp0to255(Y * oneMinusK255th + K);
+        // K in data[i + 3] is unchanged
+      }
+      return outputData;
+    },
+
+    getData: function getData(width, height, forceRGBoutput) {
+      var i;
+      var Y, Cb, Cr, K, C, M, Ye, R, G, B;
+      var colorTransform;
+      if (this.numComponents > 4) {
+        throw 'Unsupported color mode';
+      }
+      // type of data: Uint8Array(width * height * numComponents)
+      var data = this._getLinearizedBlockData(width, height);
+
+      if (this.numComponents === 3) {
+        return this._convertYccToRgb(data);
+      } else if (this.numComponents === 4) {
+        if (this._isColorConversionNeeded()) {
+          if (forceRGBoutput) {
+            return this._convertYcckToRgb(data);
+          } else {
+            return this._convertYcckToCmyk(data);
           }
-          break;
-        default:
-          throw 'Unsupported color mode';
+        } else {
+          return this._convertCmykToRgb(data);
+        }
       }
       return data;
     },
+
     copyToImageData: function copyToImageData(imageData) {
-      var width = imageData.width, height = imageData.height;
+      var width = imageData.width;
+      var height = imageData.height;
       var imageDataBytes = width * height * 4;
       var imageDataArray = imageData.data;
-      var data = this.getData(width, height);
+      var data = this.getData(width, height, /* forceRGBoutput = */true);
+
       var i = 0, j = 0;
-      var Y, K, C, M, R, G, B;
       switch (this.components.length) {
         case 1:
+          var Y;
           while (j < imageDataBytes) {
             Y = data[i++];
-
             imageDataArray[j++] = Y;
             imageDataArray[j++] = Y;
             imageDataArray[j++] = Y;
@@ -923,31 +968,11 @@ var JpegImage = (function jpegImage() {
           }
           break;
         case 3:
-          while (j < imageDataBytes) {
-            R = data[i++];
-            G = data[i++];
-            B = data[i++];
-
-            imageDataArray[j++] = R;
-            imageDataArray[j++] = G;
-            imageDataArray[j++] = B;
-            imageDataArray[j++] = 255;
-          }
-          break;
         case 4:
           while (j < imageDataBytes) {
-            C = data[i++];
-            M = data[i++];
-            Y = data[i++];
-            K = data[i++];
-
-            R = 255 - clamp0to255(C * (1 - K / 255) + K);
-            G = 255 - clamp0to255(M * (1 - K / 255) + K);
-            B = 255 - clamp0to255(Y * (1 - K / 255) + K);
-
-            imageDataArray[j++] = R;
-            imageDataArray[j++] = G;
-            imageDataArray[j++] = B;
+            imageDataArray[j++] = data[i++];
+            imageDataArray[j++] = data[i++];
+            imageDataArray[j++] = data[i++];
             imageDataArray[j++] = 255;
           }
           break;
diff --git a/src/core/image.js b/src/core/image.js
index 333aabb..f3350ba 100644
--- a/src/core/image.js
+++ b/src/core/image.js
@@ -44,6 +44,7 @@ var PDFImage = (function PDFImageClosure() {
       return Promise.resolve(image);
     }
   }
+
   /**
    * Decode and clamp a value. The formula is different from the spec because we
    * don't decode to float range [0,1], we decode it in the [0,max] range.
@@ -53,6 +54,7 @@ var PDFImage = (function PDFImageClosure() {
     // Clamp the value to the range
     return (value < 0 ? 0 : (value > max ? max : value));
   }
+
   function PDFImage(xref, res, image, inline, smask, mask, isMask) {
     this.image = image;
     var dict = image.dict;
@@ -279,11 +281,13 @@ var PDFImage = (function PDFImageClosure() {
                       this.smask && this.smask.width || 0,
                       this.mask && this.mask.width || 0);
     },
+
     get drawHeight() {
       return Math.max(this.height,
                       this.smask && this.smask.height || 0,
                       this.mask && this.mask.height || 0);
     },
+
     decodeBuffer: function PDFImage_decodeBuffer(buffer) {
       var bpc = this.bpc;
       var numComps = this.numComps;
@@ -309,6 +313,7 @@ var PDFImage = (function PDFImageClosure() {
         }
       }
     },
+
     getComponents: function PDFImage_getComponents(buffer) {
       var bpc = this.bpc;
 
@@ -385,6 +390,7 @@ var PDFImage = (function PDFImageClosure() {
       }
       return output;
     },
+
     fillOpacity: function PDFImage_fillOpacity(rgbaBuf, width, height,
                                                actualHeight, image) {
       var smask = this.smask;
@@ -451,6 +457,7 @@ var PDFImage = (function PDFImageClosure() {
         }
       }
     },
+
     undoPreblend: function PDFImage_undoPreblend(buffer, width, height) {
       var matte = this.smask && this.smask.matte;
       if (!matte) {
@@ -467,7 +474,7 @@ var PDFImage = (function PDFImageClosure() {
         var alpha = buffer[i + 3];
         if (alpha === 0) {
           // according formula we have to get Infinity in all components
-          // making it as white (tipical paper color) should be okay
+          // making it white (tipical paper color) should be okay
           buffer[i] = 255;
           buffer[i + 1] = 255;
           buffer[i + 2] = 255;
@@ -479,6 +486,7 @@ var PDFImage = (function PDFImageClosure() {
         buffer[i + 2] = clamp((buffer[i + 2] - matteRgb[2]) * k + matteRgb[2]);
       }
     },
+
     createImageData: function PDFImage_createImageData(forceRGBA) {
       var drawWidth = this.drawWidth;
       var drawHeight = this.drawHeight;
@@ -529,7 +537,6 @@ var PDFImage = (function PDFImageClosure() {
           return imgData;
         }
       }
-
       // imgArray can be incomplete (e.g. after CCITT fax encoding).
       var actualHeight = 0 | (imgArray.length / rowBytes *
                          drawHeight / originalHeight);
@@ -567,6 +574,7 @@ var PDFImage = (function PDFImageClosure() {
 
       return imgData;
     },
+
     fillGrayBuffer: function PDFImage_fillGrayBuffer(buffer) {
       var numComps = this.numComps;
       if (numComps != 1) {
@@ -589,7 +597,7 @@ var PDFImage = (function PDFImageClosure() {
         length = width * height;
         if (this.needsDecode) {
           // invert and scale to {0, 255}
-          for (i = 0; i < length; ++i) {
+          for (var i = 0; i < length; ++i) {
             buffer[i] = (comps[i] - 1) & 255;
           }
         } else {
@@ -611,6 +619,7 @@ var PDFImage = (function PDFImageClosure() {
         buffer[i] = (scale * comps[i]) | 0;
       }
     },
+
     getImageBytes: function PDFImage_getImageBytes(length) {
       this.image.reset();
       return this.image.getBytes(length);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git



More information about the Pkg-javascript-commits mailing list