First stage of trying to support smasks on native jpegs.

This commit is contained in:
Brendan Dahl 2011-12-07 15:36:27 -08:00
parent c615342962
commit 2a632d4ab2
6 changed files with 109 additions and 48 deletions

View File

@ -1038,21 +1038,24 @@ var CanvasGraphics = (function canvasGraphics() {
paintJpegXObject: function canvasGraphicsPaintJpegXObject(objId, w, h) {
var image = this.objs.get(objId);
debugger;
if (!image) {
error('Dependent image isn\'t ready yet');
}
this.paintNormalImageXObject(image);
/*
this.save();
var ctx = this.ctx;
// scale the image to the unit square
ctx.scale(1 / w, -1 / h);
var domImage = image.getImage();
ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height,
ctx.drawImage(image.data, 0, 0, image.width, image.height,
0, -h, w, h);
this.restore();
this.restore(); */
},
paintImageMaskXObject: function canvasGraphicsPaintImageMaskXObject(
@ -1104,7 +1107,7 @@ var CanvasGraphics = (function canvasGraphics() {
this.restore();
},
paintImageXObject: function canvasGraphicsPaintImageXObject(imgData) {
paintNormalImageXObject: function canvasGraphicsPaintImageXObject(imgData) {
this.save();
var ctx = this.ctx;
var w = imgData.width;
@ -1134,6 +1137,21 @@ var CanvasGraphics = (function canvasGraphics() {
this.restore();
},
paintImageXObject: function canvasGraphicsPaintImageXObject(type, data) {
debugger;
switch(type) {
case 'jpeg':
this.paintJpegXObject.apply(this, data);
break;
case 'imageMask':
this.paintImageMaskXObject.apply(this, data);
break;
default:
this.paintNormalImageXObject.apply(this, data);
break;
}
},
// Marked content
markPoint: function canvasGraphicsMarkPoint(tag) {

View File

@ -6,7 +6,7 @@
var globalScope = (typeof window === 'undefined') ? this : window;
var ERRORS = 0, WARNINGS = 1, TODOS = 5;
var verbosity = WARNINGS;
var verbosity = TODOS;
// The global PDFJS object exposes the API
// In production, it will be declared outside a global wrapper
@ -14,7 +14,7 @@ var verbosity = WARNINGS;
if (!globalScope.PDFJS) {
globalScope.PDFJS = {};
}
PDFJS.disableWorker = true;
// getPdf()
// Convenience function to perform binary Ajax GET
// Usage: getPdf('http://...', callback)
@ -440,6 +440,7 @@ var PDFDocModel = (function pdfDoc() {
this.startXRef,
this.mainXRefEntriesOffset);
this.catalog = new Catalog(this.xref);
this.objs = new PDFObjects();
},
get numPages() {
var linearization = this.linearization;
@ -559,9 +560,9 @@ var PDFDoc = (function pdfDoc() {
var type = data[1];
switch (type) {
case 'JpegStream':
var IR = data[2];
new JpegImageLoader(id, IR, this.objs);
case 'Jpeg':
var imageData = data[2];
this.objs.resolve(id, imageData);
break;
case 'Font':
var name = data[2];
@ -607,6 +608,30 @@ var PDFDoc = (function pdfDoc() {
throw data.error;
}, this);
messageHandler.on('jpeg_decode', function(message) {
var imageData = message.data[0];
var img = new Image();
img.onload = (function jpegImageLoaderOnload() {
var width = img.width;
var height = img.height;
var length = width * height * 4;
var buf = new Uint8Array(length);
var tempCanvas = new ScratchCanvas(width, height);
var tempCtx = tempCanvas.getContext('2d');
tempCtx.drawImage(img, 0, 0);
var data = tempCtx.getImageData(0, 0, width, height).data;
for (var i = 0; i < length; i += 4) {
buf[i] = data[i];
buf[i + 1] = data[i + 1];
buf[i + 2] = data[i + 2];
buf[i + 3] = data[i + 3];
}
message.resolve({ data: buf, width: width, height: height});
}).bind(this);
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
img.src = src;
});
setTimeout(function pdfDocFontReadySetTimeout() {
messageHandler.send('doc', this.data);
this.workerReadyPromise.resolve(true);

View File

@ -179,21 +179,24 @@ var PartialEvaluator = (function partialEvaluator() {
return loadedName;
}
function buildPaintImageXObject(image, inline) {
function buildPaintImageXObject(image, inline) {
var dict = image.dict;
var w = dict.get('Width', 'W');
var h = dict.get('Height', 'H');
fn = 'paintImageXObject';
if (image instanceof JpegStream && image.isNative) {
var objId = 'img_' + uniquePrefix + (++self.objIdCounter);
handler.send('obj', [objId, 'JpegStream', image.getIR()]);
debugger;
handler.send('jpeg_decode', [image.getIR()], function(data) {
handler.send('obj', [objId, 'Jpeg', data]);
});
// Add the dependency on the image object.
insertDependency([objId]);
// The normal fn.
fn = 'paintJpegXObject';
args = [objId, w, h];
args = ['jpeg', [objId, w, h]];
return;
}
@ -220,8 +223,7 @@ var PartialEvaluator = (function partialEvaluator() {
var pixels = imgData.data;
imageObj.fillRgbaBuffer(pixels, imageObj.decode);
fn = 'paintImageXObject';
args = [imgData];
args = ['normal', [imgData]];
return;
}
@ -230,7 +232,6 @@ var PartialEvaluator = (function partialEvaluator() {
// data can't be done here. Instead of creating a
// complete PDFImage, only read the information needed
// for later.
fn = 'paintImageMaskXObject';
var width = dict.get('Width', 'W');
var height = dict.get('Height', 'H');
@ -239,7 +240,7 @@ var PartialEvaluator = (function partialEvaluator() {
var decode = dict.get('Decode', 'D');
var inverseDecode = !!decode && decode[0] > 0;
args = [imgArray, inverseDecode, width, height];
args = ['imageMask', [imgArray, inverseDecode, width, height]];
}
uniquePrefix = uniquePrefix || '';

View File

@ -228,30 +228,3 @@ var PDFImage = (function pdfImage() {
};
return constructor;
})();
var JpegImageLoader = (function jpegImage() {
function JpegImageLoader(objId, imageData, objs) {
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
var img = new Image();
img.onload = (function jpegImageLoaderOnload() {
this.loaded = true;
objs.resolve(objId, this);
if (this.onLoad)
this.onLoad();
}).bind(this);
img.src = src;
this.domImage = img;
}
JpegImageLoader.prototype = {
getImage: function jpegImageLoaderGetImage() {
return this.domImage;
}
};
return JpegImageLoader;
})();

View File

@ -804,6 +804,8 @@ var JpegStream = (function jpegStream() {
this.colorTransform = -1;
this.bytes = bytes;
if (isAdobeImage(bytes)) {
// when bug 674619 land, let's check if browser can do
// normal cmyk and then we won't have to the following

View File

@ -6,6 +6,8 @@
function MessageHandler(name, comObj) {
this.name = name;
this.comObj = comObj;
this.callbackIndex = 1;
this.callbacks = {};
var ah = this.actionHandler = {};
ah['console_log'] = [function ahConsoleLog(data) {
@ -14,11 +16,38 @@ function MessageHandler(name, comObj) {
ah['console_error'] = [function ahConsoleError(data) {
console.error.apply(console, data);
}];
ah['__resolve__'] = [ function(data) {
var callbackId = data.callbackId;
if (data.callbackId in this.callbacks) {
var callback = this.callbacks[callbackId];
delete this.callbacks[callbackId];
callback(data.data);
} else {
throw 'Cannot resolve callback ' + callbackId;
}
}, this];
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
var data = event.data;
if (data.action in ah) {
var action = ah[data.action];
action[0].call(action[1], data.data);
if (data.callbackId) {
action[0].call(action[1], {
data: data.data,
resolve: (function(callbackId) {
return function(resolvedData) {
comObj.postMessage({
action: '__resolve__',
data: {
data: resolvedData,
callbackId: data.callbackId
}
});
}})(data.callbackId)
});
} else {
action[0].call(action[1], data.data);
}
} else {
throw 'Unkown action from worker: ' + data.action;
}
@ -34,11 +63,17 @@ MessageHandler.prototype = {
ah[actionName] = [handler, scope];
},
send: function messageHandlerSend(actionName, data) {
this.comObj.postMessage({
send: function messageHandlerSend(actionName, data, callback) {
var message = {
action: actionName,
data: data
});
};
if (callback) {
var callbackId = this.callbackIndex++;
this.callbacks[callbackId] = callback;
message.callbackId = callbackId;
}
this.comObj.postMessage(message);
}
};
@ -160,6 +195,13 @@ var WorkerMessageHandler = {
handler.send('font_ready', [objId, obj]);
});
handler.on('jpeg_decoded', function jpegDecoded(data) {
var objId = data[0];
var imageData = data[1];
console.log('worker recieved decoded jpeg');
debugger;
}, this);
}
};