Fixes for small colour variations in tests

https://github.com/notmasteryet/jpgjs/pull/24
This commit is contained in:
Thorben Bochenek 2014-03-25 19:02:58 -05:00 committed by Yury Delendik
parent dbbe702be5
commit 7bf0987810

126
external/jpgjs/jpg.js vendored
View File

@ -156,7 +156,7 @@ var JpegImage = (function jpegImage() {
function decodeBaseline(component, offset) {
var t = decodeHuffman(component.huffmanTableDC);
var diff = t === 0 ? 0 : receiveAndExtend(t);
component.blocks[offset] = (component.pred += diff);
component.blockData[offset] = (component.pred += diff);
var k = 1;
while (k < 64) {
var rs = decodeHuffman(component.huffmanTableAC);
@ -169,7 +169,7 @@ var JpegImage = (function jpegImage() {
}
k += r;
var z = dctZigZag[k];
component.blocks[offset + z] = receiveAndExtend(s);
component.blockData[offset + z] = receiveAndExtend(s);
k++;
}
}
@ -177,11 +177,11 @@ var JpegImage = (function jpegImage() {
function decodeDCFirst(component, offset) {
var t = decodeHuffman(component.huffmanTableDC);
var diff = t === 0 ? 0 : (receiveAndExtend(t) << successive);
component.blocks[offset] = (component.pred += diff);
component.blockData[offset] = (component.pred += diff);
}
function decodeDCSuccessive(component, offset) {
component.blocks[offset] |= readBit() << successive;
component.blockData[offset] |= readBit() << successive;
}
var eobrun = 0;
@ -204,7 +204,7 @@ var JpegImage = (function jpegImage() {
}
k += r;
var z = dctZigZag[k];
component.blocks[offset + z] = receiveAndExtend(s) * (1 << successive);
component.blockData[offset + z] = receiveAndExtend(s) * (1 << successive);
k++;
}
}
@ -235,8 +235,8 @@ var JpegImage = (function jpegImage() {
continue;
case 1: // skipping r zero items
case 2:
if (component.blocks[offset + z]) {
component.blocks[offset + z] += (readBit() << successive);
if (component.blockData[offset + z]) {
component.blockData[offset + z] += (readBit() << successive);
} else {
r--;
if (r === 0)
@ -244,16 +244,16 @@ var JpegImage = (function jpegImage() {
}
break;
case 3: // set value for a zero item
if (component.blocks[offset + z]) {
component.blocks[offset + z] += (readBit() << successive);
if (component.blockData[offset + z]) {
component.blockData[offset + z] += (readBit() << successive);
} else {
component.blocks[offset + z] = successiveACNextValue << successive;
component.blockData[offset + z] = successiveACNextValue << successive;
successiveACState = 0;
}
break;
case 4: // eob
if (component.blocks[offset + z]) {
component.blocks[offset + z] += (readBit() << successive);
if (component.blockData[offset + z]) {
component.blockData[offset + z] += (readBit() << successive);
}
break;
}
@ -363,8 +363,9 @@ var JpegImage = (function jpegImage() {
var i;
// dequant
for (i = 0; i < 64; i++)
p[i] = component.blocks[blockBufferOffset + i] * qt[i];
for (i = 0; i < 64; i++) {
p[i] = component.blockData[blockBufferOffset + i] * qt[i];
}
// inverse DCT on rows
for (i = 0; i < 8; ++i) {
@ -506,7 +507,8 @@ var JpegImage = (function jpegImage() {
// convert to 8-bit integers
for (i = 0; i < 64; ++i) {
p[i] = clampTo8bit((p[i] + 2056) >> 4);
var index = blockBufferOffset + i;
component.blockData[index] = clampTo8bitInt((p[i] + 2056) >> 4);
}
}
@ -515,35 +517,26 @@ var JpegImage = (function jpegImage() {
var blocksPerLine = component.blocksPerLine;
var blocksPerColumn = component.blocksPerColumn;
var samplesPerLine = blocksPerLine << 3;
var R = new Int16Array(64);
var computationBuffer = new Int32Array(64);
var i, j, ll = 0;
for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
var scanLine = blockRow << 3;
for (i = 0; i < 8; i++) {
lines[ll++] = new Uint8Array(samplesPerLine);
}
for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
quantizeAndInverse(component,
getBlockBufferOffset(component, blockRow, blockCol),
R);
var offset = 0, sample = blockCol << 3;
for (j = 0; j < 8; j++) {
var line = lines[scanLine + j];
for (i = 0; i < 8; i++) {
line[sample + i] = R[offset++];
}
}
var offset = getBlockBufferOffset(component, blockRow, blockCol)
quantizeAndInverse(component, offset, computationBuffer);
}
}
return lines;
return component.blockData;
}
function clampTo8bit(a) {
function clampTo8bitInt(a) {
return a <= 0 ? 0 : a >= 255 ? 255 : a | 0;
}
function clamp0to255(a) {
return a <= 0 ? 0 : a >= 255 ? 255 : a;
}
constructor.prototype = {
load: function load(path) {
var xhr = new XMLHttpRequest();
@ -586,11 +579,9 @@ var JpegImage = (function jpegImage() {
var blocksBufferSize = 64 * blocksPerColumnForMcu
* (blocksPerLineForMcu + 1);
var blocks = new Int16Array(blocksBufferSize);
component.blockData = new Int16Array(blocksBufferSize);
component.blocksPerLine = blocksPerLine;
component.blocksPerColumn = blocksPerColumn;
component.blocks = blocks;
}
frame.mcusPerLine = mcusPerLine;
frame.mcusPerColumn = mcusPerColumn;
@ -784,16 +775,19 @@ var JpegImage = (function jpegImage() {
for (var i = 0; i < frame.components.length; i++) {
var component = frame.components[i];
this.components.push({
lines: buildComponentData(frame, component),
output: buildComponentData(frame, component),
scaleX: component.h / frame.maxH,
scaleY: component.v / frame.maxV
scaleY: component.v / frame.maxV,
blocksPerLine: component.blocksPerLine,
blocksPerColumn: component.blocksPerColumn
});
}
},
getData: function getData(width, height) {
var scaleX = this.width / width, scaleY = this.height / height;
var component, componentLine, componentScaleX, componentScaleY;
var component, componentScaleX, componentScaleY;
var x, y, i;
var offset = 0;
var Y, Cb, Cr, K, C, M, Ye, R, G, B;
@ -801,17 +795,49 @@ var JpegImage = (function jpegImage() {
var numComponents = this.components.length;
var dataLength = width * height * numComponents;
var data = new Uint8Array(dataLength);
var componentLine;
// lineData is reused for all components. Assume first component is
// the biggest
var lineData = new Uint8Array((this.components[0].blocksPerLine << 3) *
this.components[0].blocksPerColumn * 8);
// First construct image data ...
for (i = 0; i < numComponents; i++) {
component = this.components[i];
var blocksPerLine = component.blocksPerLine;
var blocksPerColumn = component.blocksPerColumn;
var samplesPerLine = blocksPerLine << 3;
var j, k, ll = 0;
var lineOffset = 0;
for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
var scanLine = blockRow << 3;
for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
var bufferOffset = getBlockBufferOffset(component, blockRow, blockCol);
var offset = 0, sample = blockCol << 3;
for (j = 0; j < 8; j++) {
var lineOffset = (scanLine + j) * samplesPerLine;
for (k = 0; k < 8; k++) {
lineData[lineOffset + sample + k] =
component.output[bufferOffset + offset++];
}
}
}
}
componentScaleX = component.scaleX * scaleX;
componentScaleY = component.scaleY * scaleY;
offset = i;
var cx, cy;
var index;
for (y = 0; y < height; y++) {
componentLine = component.lines[0 | (y * componentScaleY)];
for (x = 0; x < width; x++) {
data[offset] = componentLine[0 | (x * componentScaleX)];
cy = 0 | (y * componentScaleY);
cx = 0 | (x * componentScaleX);
index = cy * samplesPerLine + cx;
data[offset] = lineData[index];
offset += numComponents;
}
}
@ -837,9 +863,9 @@ var JpegImage = (function jpegImage() {
Cb = data[i + 1];
Cr = data[i + 2];
R = clampTo8bit(Y + 1.402 * (Cr - 128));
G = clampTo8bit(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128));
B = clampTo8bit(Y + 1.772 * (Cb - 128));
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;
@ -862,9 +888,9 @@ var JpegImage = (function jpegImage() {
Cb = data[i + 1];
Cr = data[i + 2];
C = 255 - clampTo8bit(Y + 1.402 * (Cr - 128));
M = 255 - clampTo8bit(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128));
Ye = 255 - clampTo8bit(Y + 1.772 * (Cb - 128));
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;
@ -915,9 +941,9 @@ var JpegImage = (function jpegImage() {
Y = data[i++];
K = data[i++];
R = 255 - clampTo8bit(C * (1 - K / 255) + K);
G = 255 - clampTo8bit(M * (1 - K / 255) + K);
B = 255 - clampTo8bit(Y * (1 - K / 255) + K);
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;