1
0
Fork 0
forked from 0x2620/oxjs

image module update

This commit is contained in:
rlx 2011-09-08 21:39:07 +00:00
commit 1e38ff6b9e
4 changed files with 188 additions and 152 deletions

View file

@ -1857,6 +1857,17 @@ Ox.element = function(str) {
return ret;
},
/*@
click <f> Binds a function to the click event
(callback) -> <o> This element
callback <f> Callback function
event <o> The DOM event
@*/
// fixme: why not a generic bind?
click: function(callback) {
this[0].onclick = callback;
return this;
},
/*@
css <f> Gets or sets a CSS attribute
(key) -> <s> Value
(key, value) -> <o> This element
@ -1912,6 +1923,15 @@ Ox.element = function(str) {
return this;
},
/*@
removeAttr <f> Removes an attribute
(key) -> <o> This element
key <s> The attribute
@*/
removeAttr: function(key) {
this[0].removeAttribute(key);
return this;
},
/*@
removeClass <f> Removes a class name
(className) -> <o> This element
className <s> Class name
@ -2092,13 +2112,12 @@ Ox.element = function(str) {
// Make sure we can encode the full unicode range of characters.
str = Ox.encodeUTF8(str);
// We can only safely write to RGB, so we need 1 pixel for 3 bytes.
var len = str.length, c = Ox.canvas(Math.ceil((4 + len) / 3), 1),
data = '', idat;
// Prefix the string with its length, left-padded with 0-bytes to
// length of 4 bytes, and right-pad the result with non-0-bytes to a
// length that is a multiple of 3.
str = Ox.pad(Ox.pad(Ox.encodeBase256(len), 4, '\u0000') + str,
-Math.ceil((4 + len) / 3) * 3, '\u00FF');
// The string length may not be a multiple of 3, so we need to encode
// the number of padding bytes (1 byte), the string, and non-0-bytes
// as padding, so that the combined length becomes a multiple of 3.
var len = 1 + str.length, c = Ox.canvas(Math.ceil(len / 3), 1),
data, idat, pad = (3 - len % 3) % 3;
str = Ox.char(pad) + str + Ox.repeat('\u00FF', pad);
Ox.loop(c.data.length, function(i) {
// Write character codes into RGB, and 255 into ALPHA
c.data[i] = i % 4 < 3 ? str.charCodeAt(i - parseInt(i / 4)) : 255;
@ -2106,15 +2125,17 @@ Ox.element = function(str) {
c.context.putImageData(c.imageData, 0, 0);
// Get the PNG data from the data URL and decode it from base64.
str = atob(c.canvas.toDataURL().split(',')[1]);
// The first 16 and the last 12 bytes of a PNG are always the same and
// can be discarded, the first 17 remaining bytes are part of the IHDR
// chunk, and the rest are IDAT chunks.
data = Ox.sub(str, 16, 33); idat = Ox.sub(str, 33, -12);
// Discard bytes 0 to 15 (8 bytes PNG signature, 4 bytes IHDR length, 4
// bytes IHDR name), keep bytes 16 to 19 (width), discard bytes 20 to 29
// (4 bytes height, 5 bytes flags), keep bytes 29 to 32 (IHDR checksum),
// keep the rest (IDAT chunks), discard the last 12 bytes (IEND chunk).
data = str.substr(16, 4) + str.substr(29, 4);
idat = str.substr(33, str.length - 45);
while (idat) {
// Each IDAT chunk consists of 4 bytes length, 4 bytes "IDAT" and
// length bytes data, so we can optimize by removing each "IDAT".
// Each IDAT chunk is 4 bytes length, 4 bytes name, length bytes
// data and 4 bytes checksum. We can discard the name parts.
len = idat.substr(0, 4);
data += len + idat.substr(8, 12 + (len = Ox.decodeBase256(len)));
data += len + idat.substr(8, 4 + (len = Ox.decodeBase256(len)));
idat = idat.substr(12 + len);
}
callback && callback(data);
@ -2135,24 +2156,24 @@ Ox.element = function(str) {
@*/
Ox.decodeDeflate = function(str, callback) {
function decodeHex(str) {
return str.split(' ').map(function(v) {
return Ox.char(parseInt(v, 16));
}).join('');
}
var image = new Image(),
// The first 16 and the last 12 bytes of a PNG are always the same,
// the first 17 remaining bytes are part of the IHDR chunk, and the
// rest are IDAT chunks.
head = decodeHex('89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52'),
tail = decodeHex('00 00 00 00 49 45 4E 44 AE 42 60 82'),
data = '', ihdr = str.substr(0, 17), idat = str.substr(17), len;
// PNG file signature and IHDR chunk
data = '\u0089PNG\r\n\u001A\n\u0000\u0000\u0000\u000DIHDR'
+ str.substr(0, 4) + '\u0000\u0000\u0000\u0001'
+ '\u0008\u0006\u0000\u0000\u0000' + str.substr(4, 4),
// IDAT chunks
idat = str.substr(8), len;
function error() {
throw new RangeError('Deflate codec can\'t decode data.');
}
while (idat) {
// Reinsert the IDAT chunk names
len = idat.substr(0, 4);
data += len + 'IDAT' + idat.substr(4, 8 + (len = Ox.decodeBase256(len)));
data += len + 'IDAT' + idat.substr(4, 4 + (len = Ox.decodeBase256(len)));
idat = idat.substr(8 + len);
}
// IEND chunk
data += '\u0000\u0000\u0000\u0000IEND\u00AE\u0042\u0060\u0082';
// Unfortunately, we can't synchronously set the source of an image,
// draw it onto a canvas, and read its data.
image.onload = function() {
@ -2160,16 +2181,17 @@ Ox.element = function(str) {
// Read one character per RGB byte, ignore ALPHA.
return i % 4 < 3 ? Ox.char(v) : '';
}).join('');
callback(
// Parse the first 4 bytes as length and the next length bytes
// as an UTF8-encoded string.
Ox.decodeUTF8(str.substr(4, Ox.decodeBase256(str.substr(0, 4))))
);
try {
// Parse the first byte as number of bytes to chop at the end,
// and the rest, without these bytes, as an UTF8-encoded string.
str = Ox.decodeUTF8(str.substr(1, str.length - 1 - str.charCodeAt(0)))
} catch (e) {
error();
}
callback(str);
}
image.onerror = function() {
throw new RangeError('Deflate codec can\'t decode data.')
}
image.src = 'data:image/png;base64,' + btoa(head + ihdr + data + tail);
image.onerror = error;
image.src = 'data:image/png;base64,' + btoa(data);
}
/*@