Half working version of paintImageXObject
This commit is contained in:
		
							parent
							
								
									c326f1808f
								
							
						
					
					
						commit
						5da69f520d
					
				
							
								
								
									
										215
									
								
								pdf.js
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								pdf.js
									
									
									
									
									
								
							@ -1894,7 +1894,7 @@ var CanvasGraphics = (function() {
 | 
				
			|||||||
            var type = xobj.dict.get("Subtype");
 | 
					            var type = xobj.dict.get("Subtype");
 | 
				
			||||||
            assertWellFormed(IsName(type), "XObject should have a Name subtype");
 | 
					            assertWellFormed(IsName(type), "XObject should have a Name subtype");
 | 
				
			||||||
            if ("Image" == type.name) {
 | 
					            if ("Image" == type.name) {
 | 
				
			||||||
                this.paintImageXObject(xobj);
 | 
					                this.paintImageXObject(xobj, false);
 | 
				
			||||||
            } else if ("Form" == type.name) {
 | 
					            } else if ("Form" == type.name) {
 | 
				
			||||||
                this.paintFormXObject(xobj);
 | 
					                this.paintFormXObject(xobj);
 | 
				
			||||||
            } else if ("PS" == type.name) {
 | 
					            } else if ("PS" == type.name) {
 | 
				
			||||||
@ -1924,16 +1924,23 @@ var CanvasGraphics = (function() {
 | 
				
			|||||||
            this.restore();
 | 
					            this.restore();
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        paintImageXObject: function(image) {
 | 
					        paintImageXObject: function(image, inline) {
 | 
				
			||||||
            this.save();
 | 
					            this.save();
 | 
				
			||||||
 | 
					            this.ctx.scale(.0066,.02);
 | 
				
			||||||
 | 
					            if (image.getParams) {
 | 
				
			||||||
 | 
					                // JPX/JPEG2000 streams directly contain bits per component
 | 
				
			||||||
 | 
					                // and color space mode information.
 | 
				
			||||||
 | 
					                TODO("get params from actual stream");
 | 
				
			||||||
 | 
					                // var bits = ...
 | 
				
			||||||
 | 
					                // var colorspace = ...
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            // TODO cache rendered images?
 | 
					            // TODO cache rendered images?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var dict = image.dict;
 | 
					            var dict = image.dict;
 | 
				
			||||||
            var w = dict.get("Width") || dict.get("W");
 | 
					            var w = dict.get("Width") || dict.get("W");
 | 
				
			||||||
            var h = dict.get("Height") || dict.get("H");
 | 
					            var h = dict.get("Height") || dict.get("H");
 | 
				
			||||||
           
 | 
					           
 | 
				
			||||||
            if (w < 1 || h < 1)
 | 
					            if (!IsNum(w) || !IsNum(h) || w < 1 || h < 1)
 | 
				
			||||||
                error("Invalid image width or height");
 | 
					                error("Invalid image width or height");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var interpolate = dict.get("Interpolate") || dict.get("I");
 | 
					            var interpolate = dict.get("Interpolate") || dict.get("I");
 | 
				
			||||||
@ -1943,11 +1950,7 @@ var CanvasGraphics = (function() {
 | 
				
			|||||||
            if (!IsBool(imageMask))
 | 
					            if (!IsBool(imageMask))
 | 
				
			||||||
                imageMask = false;
 | 
					                imageMask = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // JPX/JPEG2000 streams directly contain bits per component
 | 
					 | 
				
			||||||
            // and color space mode information.
 | 
					 | 
				
			||||||
            var bitsPerComponent = image.bitsPerComponent;
 | 
					            var bitsPerComponent = image.bitsPerComponent;
 | 
				
			||||||
            var csMode = image.csMode;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!bitsPerComponent) {
 | 
					            if (!bitsPerComponent) {
 | 
				
			||||||
                bitsPerComponent = dict.get("BitsPerComponent") || dict.get("BPC");
 | 
					                bitsPerComponent = dict.get("BitsPerComponent") || dict.get("BPC");
 | 
				
			||||||
                if (!bitsPerComponent) {
 | 
					                if (!bitsPerComponent) {
 | 
				
			||||||
@ -1958,53 +1961,142 @@ var CanvasGraphics = (function() {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (bitsPerComponent !== 8)
 | 
				
			||||||
 | 
					                error("Unsupported bpc");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var xref = this.xref;
 | 
				
			||||||
 | 
					            var colorSpaces = this.colorSpaces;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (imageMask) {
 | 
				
			||||||
 | 
					                error("support image masks");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // actual image
 | 
				
			||||||
 | 
					            var csStream = dict.get("ColorSpace") || dict.get("CS");
 | 
				
			||||||
 | 
					            csStream = xref.fetchIfRef(csStream);
 | 
				
			||||||
 | 
					            if (IsName(csStream) && inline) 
 | 
				
			||||||
 | 
					                csStream = colorSpaces.get(csStream);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            var colorSpace = new ColorSpace(xref, csStream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var decode = dict.get("Decode") || dict.get("D");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            TODO("create color map");
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            var mask = image.dict.get("Mask");
 | 
				
			||||||
 | 
					            mask = this.xref.fetchIfRef(mask);
 | 
				
			||||||
 | 
					            var smask = image.dict.get("SMask");
 | 
				
			||||||
 | 
					            smask = this.xref.fetchIfRef(smask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (IsStream(smask)) {
 | 
				
			||||||
 | 
					                if (inline)
 | 
				
			||||||
 | 
					                    error("cannot combine smask and inlining");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var maskDict = smask.dict;
 | 
				
			||||||
 | 
					                var maskW = maskDict.get("Width") || maskDict.get("W");
 | 
				
			||||||
 | 
					                var maskH = maskDict.get("Height") || maskDict.get("H");
 | 
				
			||||||
 | 
					                if (!IsNum(maskW) || !IsNum(maskH) || maskW < 1 || maskH < 1)
 | 
				
			||||||
 | 
					                    error("Invalid image width or height");
 | 
				
			||||||
 | 
					                if (maskW !== w || maskH !== h)
 | 
				
			||||||
 | 
					                    error("Invalid image width or height");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var maskInterpolate = maskDict.get("Interpolate") || maskDict.get("I");
 | 
				
			||||||
 | 
					                if (!IsBool(maskInterpolate))
 | 
				
			||||||
 | 
					                    maskInterpolate = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var maskBPC = maskDict.get("BitsPerComponent") 
 | 
				
			||||||
 | 
					                    || maskDict.get("BPC");
 | 
				
			||||||
 | 
					                if (!maskBPC)
 | 
				
			||||||
 | 
					                    error("Invalid image mask bpc");
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					                var maskCsStream = maskDict.get("ColorSpace") 
 | 
				
			||||||
 | 
					                    || maskDict.get("CS");
 | 
				
			||||||
 | 
					                maskCsStream = xref.fetchIfRef(maskCsStream);
 | 
				
			||||||
 | 
					                //if (IsName(maskCsStream)) 
 | 
				
			||||||
 | 
					                //    maskCsStream = colorSpaces.get(maskCsStream);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					                var maskColorSpace = new ColorSpace(xref, maskCsStream);
 | 
				
			||||||
 | 
					                if (maskColorSpace.mode !== "DeviceGray")
 | 
				
			||||||
 | 
					                    error("Invalid color space for smask");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var maskDecode = maskDict.get("Decode") || maskDict.get("D");
 | 
				
			||||||
 | 
					                if (maskDecode)
 | 
				
			||||||
 | 
					                    TODO("Handle mask decode");
 | 
				
			||||||
 | 
					                // handle matte object 
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                smask = null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var tmpCanvas = document.createElement("canvas");
 | 
					            var tmpCanvas = document.createElement("canvas");
 | 
				
			||||||
            tmpCanvas.width = w;
 | 
					            tmpCanvas.width = w;
 | 
				
			||||||
            tmpCanvas.height = h;
 | 
					            tmpCanvas.height = h;
 | 
				
			||||||
 | 
					//            tmpCanvas.mozOpaque = false;
 | 
				
			||||||
 | 
					            var ctx = this.ctx;
 | 
				
			||||||
            var tmpCtx = tmpCanvas.getContext("2d");
 | 
					            var tmpCtx = tmpCanvas.getContext("2d");
 | 
				
			||||||
 | 
					            tmpCtx.fillStyle = "rgb(255, 255, 255)";
 | 
				
			||||||
 | 
					            tmpCtx.fillRect(0, 0, w, h);
 | 
				
			||||||
            var imgData = tmpCtx.getImageData(0, 0, w, h);
 | 
					            var imgData = tmpCtx.getImageData(0, 0, w, h);
 | 
				
			||||||
            var pixels = imgData.data;
 | 
					            var pixels = imgData.data;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            var alpha = 25;
 | 
					 | 
				
			||||||
            if (image.dict.has("SMask")) {
 | 
					 | 
				
			||||||
                var smask = image.dict.get("SMask");
 | 
					 | 
				
			||||||
                smask = this.xref.fetchIfRef(smask);
 | 
					 | 
				
			||||||
                // Specifies either a shape or opacity mask to be
 | 
					 | 
				
			||||||
                // applied to the image samples
 | 
					 | 
				
			||||||
                TODO("SMask");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (smask) {
 | 
					            if (smask) {
 | 
				
			||||||
                var smaskDict = smask.dict;
 | 
					                if (maskColorSpace.numComps != 1)
 | 
				
			||||||
                if (!smaskDict)
 | 
					                    error("Incorrect number of components in smask");
 | 
				
			||||||
                    error("No dictionary for smask");
 | 
					 | 
				
			||||||
                var smaskBitsPerComponent = smaskDict.get("BitsPerComponent") || smaskDict.get("BPC");
 | 
					 | 
				
			||||||
                if (!smaskBitsPerComponent)
 | 
					 | 
				
			||||||
                    error("Bad BPC for smask");
 | 
					 | 
				
			||||||
                var max = (1 << bitsPerComponent) - 1;
 | 
					 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                var matte = smaskDict.get("Matte");
 | 
					                var numComps = colorSpace.numComps;
 | 
				
			||||||
                if (matte) {
 | 
					                // factor in bits per component
 | 
				
			||||||
                    TODO(matte);
 | 
					                var imgArray = image.getBytes(numComps * w * h);
 | 
				
			||||||
 | 
					                var imgIdx = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var smArray = smask.getBytes(w * h);
 | 
				
			||||||
 | 
					                var smIdx = 0;
 | 
				
			||||||
 | 
					               
 | 
				
			||||||
 | 
					                // hoist out loop end
 | 
				
			||||||
 | 
					                for (var i = 0; i < 4 * w * h; i+=4) {
 | 
				
			||||||
 | 
					                    var alpha = smArray[smIdx++];
 | 
				
			||||||
 | 
					                    var alphaComp = (1 << maskBPC) - 1 - alpha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    switch (numComps) {
 | 
				
			||||||
 | 
					                    case 1:
 | 
				
			||||||
 | 
					                        var p = imgArray[imageIdx++]*alpha;
 | 
				
			||||||
 | 
					                        pixels[i] = (p + pixels[i]*alphaComp) >> maskBPC;
 | 
				
			||||||
 | 
					                        pixels[i+1] = (p + pixels[i+1]*alphaComp) >> maskBPC;
 | 
				
			||||||
 | 
					                        pixels[i+2] = (p + pixels[i+2]*alphaComp) >> maskBPC;
 | 
				
			||||||
 | 
					                        pixels[i+3] = 255;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case 3:
 | 
				
			||||||
 | 
					                        pixels[i] = imgArray[imgIdx++]; //*alpha) >> maskBPC;
 | 
				
			||||||
 | 
					                        pixels[i+1] = imgArray[imgIdx++];//*alpha) >> maskBPC;
 | 
				
			||||||
 | 
					                        pixels[i+2] = imgArray[imgIdx++];//*alpha) >> maskBPC;
 | 
				
			||||||
 | 
					                        pixels[i+3] = alpha;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    default:
 | 
				
			||||||
 | 
					                        error("unhandled amount of components per pixel: " + numComps);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                for (var i = 0; i < 4 * w * h; ++i) {
 | 
					 | 
				
			||||||
                    pixels[i] = image.getChar() * smask.getChar() / max;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                for (var i = 0; i < 4 * w * h; ++i) {
 | 
					                var numComps = colorSpace.numComps;
 | 
				
			||||||
                    // TODO blend if SMask is a mask image
 | 
					                for (var i = 0; i < 4 * w * h; i+=4) {
 | 
				
			||||||
                    if (3 === i % 4) {
 | 
					                    switch (numComps) {
 | 
				
			||||||
                        pixels[i] = alpha;
 | 
					                    case 1:
 | 
				
			||||||
                    } else {
 | 
					                        var t = image.getByte();
 | 
				
			||||||
                        pixels[i] = image.getChar();
 | 
					                        pixels[i] = t;
 | 
				
			||||||
 | 
					                        pixels[i+1] = t;
 | 
				
			||||||
 | 
					                        pixels[i+2] = t;
 | 
				
			||||||
 | 
					                        pixels[i+3] = 255;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case 3:
 | 
				
			||||||
 | 
					                        pixels[i] = image.getByte();
 | 
				
			||||||
 | 
					                        pixels[i+1] = image.getByte();
 | 
				
			||||||
 | 
					                        pixels[i+2] = image.getByte();
 | 
				
			||||||
 | 
					                        pixels[i+3] = 255;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    default:
 | 
				
			||||||
 | 
					                        error("unhandled amount of components per pixel: " + numComps);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            tmpCtx.putImageData(imgData, 0, 0);
 | 
					            tmpCtx.putImageData(imgData, 0, 0);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            this.ctx.drawImage(tmpCanvas, 0, 0);
 | 
					            this.ctx.drawImage(tmpCanvas, 0, 0);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            this.restore();
 | 
					            this.restore();
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2044,6 +2136,53 @@ var CanvasGraphics = (function() {
 | 
				
			|||||||
    return constructor;
 | 
					    return constructor;
 | 
				
			||||||
})();
 | 
					})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var ColorSpace = (function() {
 | 
				
			||||||
 | 
					    function constructor(xref, cs) {
 | 
				
			||||||
 | 
					        if (IsName(cs)) {
 | 
				
			||||||
 | 
					            var mode = cs.name;
 | 
				
			||||||
 | 
					            this.mode = mode;
 | 
				
			||||||
 | 
					            switch(mode) {
 | 
				
			||||||
 | 
					            case "DeviceGray":
 | 
				
			||||||
 | 
					            case "G":
 | 
				
			||||||
 | 
					                this.numComps = 1;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            TODO("fill in color space constructor");
 | 
				
			||||||
 | 
					        } else if (IsArray(cs)) {
 | 
				
			||||||
 | 
					            var mode = cs[0].name;
 | 
				
			||||||
 | 
					            this.mode = mode;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            var stream = cs[1];
 | 
				
			||||||
 | 
					            stream = xref.fetchIfRef(stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (mode) {
 | 
				
			||||||
 | 
					            case "DeviceGray":
 | 
				
			||||||
 | 
					            case "G":
 | 
				
			||||||
 | 
					                this.stream = stream;
 | 
				
			||||||
 | 
					                this.dict = stream.dict;
 | 
				
			||||||
 | 
					                this.numComps = 1;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case "ICCBased":
 | 
				
			||||||
 | 
					                var dict = stream.dict;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                this.stream = stream;
 | 
				
			||||||
 | 
					                this.dict = dict;
 | 
				
			||||||
 | 
					                this.numComps = dict.get("N");
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                error("unrecognized color space object");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            error("unrecognized color space object");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    constructor.prototype = {
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return constructor;
 | 
				
			||||||
 | 
					})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function runParseTests() {
 | 
					function runParseTests() {
 | 
				
			||||||
    var data = snarf("paper.pdf", "binary");
 | 
					    var data = snarf("paper.pdf", "binary");
 | 
				
			||||||
    var pdf = new PDFDoc(new Stream(data));
 | 
					    var pdf = new PDFDoc(new Stream(data));
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user