On 10/03/2012 02:39 PM, Aric Stewart wrote: ACK; the first patch is also ACK'd, modulo the question re data initialization. Cheers, Jeremy > the alpha layering is not well tested > > Signed-off-by: Aric Stewart <aric@xxxxxxxxxxxxxxx> > --- > display.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++------ > spicetype.js | 31 +++++++++++++++++++++ > 2 files changed, 108 insertions(+), 9 deletions(-) > > diff --git a/display.js b/display.js > index d3429da..9f1e3dd 100644 > --- a/display.js > +++ b/display.js > @@ -207,6 +207,47 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg) > > return true; > } > + else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA) > + { > + if (! draw_copy.data.src_bitmap.jpeg_alpha) > + { > + this.log_warn("FIXME: DrawCopy could not handle this JPEG ALPHA file."); > + return false; > + } > + > + // FIXME - how lame is this. Be have it in binary format, and we have > + // to put it into string to get it back into jpeg. Blech. > + var tmpstr = "data:image/jpeg,"; > + var img = new Image; > + var i; > + var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg_alpha.data); > + for (i = 0; i < qdv.length; i++) > + { > + tmpstr += '%'; > + if (qdv[i] < 16) > + tmpstr += '0'; > + tmpstr += qdv[i].toString(16); > + } > + > + img.o = + { base: draw_copy.base, > + tag: "jpeg." + draw_copy.data.src_bitmap.surface_id, > + descriptor : draw_copy.data.src_bitmap.descriptor, > + sc : this, > + }; > + > + if (this.surfaces[draw_copy.base.surface_id].format == SPICE_SURFACE_FMT_32_ARGB) > + { > + > + var canvas = this.surfaces[draw_copy.base.surface_id].canvas; > + img.alpha_img = convert_spice_lz_to_web(canvas.context, > + draw_copy.data.src_bitmap.jpeg_alpha.alpha); > + } > + img.onload = handle_draw_jpeg_onload; > + img.src = tmpstr; > + > + return true; > + } > else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_BITMAP) > { > var canvas = this.surfaces[draw_copy.base.surface_id].canvas; > @@ -707,18 +748,45 @@ function handle_draw_jpeg_onload() > else > context = this.o.sc.surfaces[this.o.base.surface_id].canvas.context; > > - context.drawImage(this, this.o.base.box.left, this.o.base.box.top); > + if (this.alpha_img) > + { > + var c = document.createElement("canvas"); > + var t = c.getContext("2d"); > + c.setAttribute('width', this.alpha_img.width); > + c.setAttribute('height', this.alpha_img.height); > + t.putImageData(this.alpha_img, 0, 0); > + t.globalCompositeOperation = 'source-in'; > + t.drawImage(this, 0, 0); > + + context.drawImage(c, this.o.base.box.left, this.o.base.box.top); > + > + if (this.o.descriptor && + (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) > + { > + if (! ("cache" in this.o.sc)) > + this.o.sc.cache = []; > > - if (this.o.descriptor && - (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) > + this.o.sc.cache[this.o.descriptor.id] = + t.getImageData(0, 0, > + this.alpha_img.width, > + this.alpha_img.height); > + } > + } > + else > { > - if (! ("cache" in this.o.sc)) > - this.o.sc.cache = []; > + context.drawImage(this, this.o.base.box.left, this.o.base.box.top); > > - this.o.sc.cache[this.o.descriptor.id] = - context.getImageData(this.o.base.box.left, this.o.base.box.top, > - this.o.base.box.right - this.o.base.box.left, > - this.o.base.box.bottom - this.o.base.box.top); > + if (this.o.descriptor && + (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) > + { > + if (! ("cache" in this.o.sc)) > + this.o.sc.cache = []; > + > + this.o.sc.cache[this.o.descriptor.id] = + context.getImageData(this.o.base.box.left, this.o.base.box.top, > + this.o.base.box.right - this.o.base.box.left, > + this.o.base.box.bottom - this.o.base.box.top); > + } > } > > if (temp_canvas == null) > diff --git a/spicetype.js b/spicetype.js > index e006d74..758f37a 100644 > --- a/spicetype.js > +++ b/spicetype.js > @@ -234,6 +234,37 @@ SpiceImage.prototype = > at += this.jpeg.data.byteLength; > } > > + if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA) > + { > + this.jpeg_alpha = new Object; > + this.jpeg_alpha.flags = dv.getUint8(at, true); at += 1; > + this.jpeg_alpha.jpeg_size = dv.getUint32(at, true); at += 4; > + this.jpeg_alpha.data_size = dv.getUint32(at, true); at += 4; > + this.jpeg_alpha.data = mb.slice(at, this.jpeg_alpha.jpeg_size + at); > + at += this.jpeg_alpha.data.byteLength; > + // Alpha channel is an LZ image > + this.jpeg_alpha.alpha = new Object(); > + this.jpeg_alpha.alpha.length = this.jpeg_alpha.data_size - this.jpeg_alpha.jpeg_size; > + var initial_at = at; > + this.jpeg_alpha.alpha.magic = ""; > + for (var i = 3; i >= 0; i--) > + this.jpeg_alpha.alpha.magic += String.fromCharCode(dv.getUint8(at + i)); > + at += 4; > + > + // NOTE: The endian change is *correct* > + this.jpeg_alpha.alpha.version = dv.getUint32(at); at += 4; > + this.jpeg_alpha.alpha.type = dv.getUint32(at); at += 4; > + this.jpeg_alpha.alpha.width = dv.getUint32(at); at += 4; > + this.jpeg_alpha.alpha.height = dv.getUint32(at); at += 4; > + this.jpeg_alpha.alpha.stride = dv.getUint32(at); at += 4; > + this.jpeg_alpha.alpha.top_down = dv.getUint32(at); at += 4; > + > + var header_size = at - initial_at; > + > + this.jpeg_alpha.alpha.data = mb.slice(at, this.jpeg_alpha.alpha.length + at - header_size); > + at += this.jpeg_alpha.alpha.data.byteLength; > + } > + > if (this.descriptor.type == SPICE_IMAGE_TYPE_QUIC) > { > this.quic = new SpiceQuic; > > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel