diff --git a/src/core/image.js b/src/core/image.js index 8c7d8d4e0..424817f36 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -383,7 +383,7 @@ var PDFImage = (function PDFImageClosure() { rgbaBuf[j] = alphaBuf[i]; } } else { - // Common case: no mask (and no need to allocate the extra buffer). + // No mask. for (var i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) { rgbaBuf[j] = 255; } @@ -467,23 +467,35 @@ var PDFImage = (function PDFImageClosure() { var comps = this.getComponents(imgArray); - var rgbaBuf = new Uint8Array(drawWidth * drawHeight * 4); - - // Handle opacity here since color key masking needs to be performed on - // undecoded values. - this.fillOpacity(rgbaBuf, drawWidth, drawHeight, actualHeight, comps); + // If opacity data is present, use RGBA_32BPP form. Otherwise, use the + // more compact RGB_24BPP form if allowable. + var alpha01, maybeUndoPreblend; + if (!forceRGBA && !this.smask && !this.mask) { + imgData.kind = ImageKind.RGB_24BPP; + imgData.data = new Uint8Array(drawWidth * drawHeight * 3); + alpha01 = 0; + maybeUndoPreblend = false; + } else { + imgData.kind = ImageKind.RGBA_32BPP; + imgData.data = new Uint8Array(drawWidth * drawHeight * 4); + alpha01 = 1; + maybeUndoPreblend = true; + + // Color key masking (opacity) must be performed before decoding. + this.fillOpacity(imgData.data, drawWidth, drawHeight, actualHeight, + comps); + } if (this.needsDecode) { this.decodeBuffer(comps); } + this.colorSpace.fillRgb(imgData.data, originalWidth, originalHeight, + drawWidth, drawHeight, actualHeight, bpc, comps, + alpha01); + if (maybeUndoPreblend) { + this.undoPreblend(imgData.data, drawWidth, actualHeight); + } - this.colorSpace.fillRgb(rgbaBuf, originalWidth, originalHeight, drawWidth, - drawHeight, actualHeight, bpc, comps); - - this.undoPreblend(rgbaBuf, drawWidth, actualHeight); - - imgData.kind = ImageKind.RGBA_32BPP; - imgData.data = rgbaBuf; return imgData; }, fillGrayBuffer: function PDFImage_fillGrayBuffer(buffer) { diff --git a/src/shared/colorspace.js b/src/shared/colorspace.js index 9273794ee..83340d601 100644 --- a/src/shared/colorspace.js +++ b/src/shared/colorspace.js @@ -74,11 +74,13 @@ var ColorSpace = (function ColorSpaceClosure() { return false; }, /** - * Fills in the RGB colors in an RGBA buffer. + * Fills in the RGB colors in the destination buffer. alpha01 indicates + * how many alpha components there are in the dest array; it will be either + * 0 (RGB array) or 1 (RGBA array). */ - fillRgb: function ColorSpace_fillRgb(rgbaBuf, originalWidth, + fillRgb: function ColorSpace_fillRgb(dest, originalWidth, originalHeight, width, height, - actualHeight, bpc, comps) { + actualHeight, bpc, comps, alpha01) { var count = originalWidth * originalHeight; var rgbBuf = null; var numComponentColors = 1 << bpc; @@ -108,14 +110,14 @@ var ColorSpace = (function ColorSpaceClosure() { /* alpha01 = */ 0); if (!needsResizing) { - // Fill in the RGB values directly into |rgbaBuf|. - var rgbaPos = 0; + // Fill in the RGB values directly into |dest|. + var destPos = 0; for (var i = 0; i < count; ++i) { var key = comps[i] * 3; - rgbaBuf[rgbaPos++] = colorMap[key]; - rgbaBuf[rgbaPos++] = colorMap[key + 1]; - rgbaBuf[rgbaPos++] = colorMap[key + 2]; - rgbaPos++; + dest[destPos++] = colorMap[key]; + dest[destPos++] = colorMap[key + 1]; + dest[destPos++] = colorMap[key + 2]; + destPos += alpha01; } } else { rgbBuf = new Uint8Array(count * 3); @@ -129,9 +131,9 @@ var ColorSpace = (function ColorSpaceClosure() { } } else { if (!needsResizing) { - // Fill in the RGB values directly into |rgbaBuf|. - this.getRgbBuffer(comps, 0, width * actualHeight, rgbaBuf, 0, bpc, - /* alpha01 = */ 1); + // Fill in the RGB values directly into |dest|. + this.getRgbBuffer(comps, 0, width * actualHeight, dest, 0, bpc, + alpha01); } else { rgbBuf = new Uint8Array(count * 3); this.getRgbBuffer(comps, 0, count, rgbBuf, 0, bpc, @@ -145,11 +147,12 @@ var ColorSpace = (function ColorSpaceClosure() { originalHeight, width, height); } var rgbPos = 0; - var actualLength = width * actualHeight * 4; - for (var i = 0; i < actualLength; i += 4) { - rgbaBuf[i] = rgbBuf[rgbPos++]; - rgbaBuf[i + 1] = rgbBuf[rgbPos++]; - rgbaBuf[i + 2] = rgbBuf[rgbPos++]; + var destPos = 0; + for (var i = 0, ii = width * actualHeight; i < ii; i++) { + dest[destPos++] = rgbBuf[rgbPos++]; + dest[destPos++] = rgbBuf[rgbPos++]; + dest[destPos++] = rgbBuf[rgbPos++]; + destPos += alpha01; } } },