PageRenderTime 52ms CodeModel.GetById 10ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 1ms

/image/test/unit/test_encoder_png.js

http://github.com/zpao/v8monkey
JavaScript | 256 lines | 183 code | 57 blank | 16 comment | 9 complexity | 362ce7951d48d97eafb2184369a34f1e MD5 | raw file
  1/*
  2 * Test for PNG encoding in libpr0n
  3 *
  4 */
  5
  6const Ci = Components.interfaces;
  7const Cc = Components.classes;
  8
  9var png1A = {
 10        // A 3x3 image, rows are red, green, blue.
 11        // RGB format, transparency defaults.
 12
 13        transparency : null,
 14
 15        frames  : [
 16                {
 17                        width  : 3,    height : 3,
 18
 19                        format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9,
 20
 21                        pixels : [
 22                                255,0,0,  255,0,0, 255,0,0,
 23                                0,255,0,  0,255,0, 0,255,0,
 24                                0,0,255,  0,0,255, 0,0,255,
 25                                ]
 26                }
 27
 28                ],
 29        expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
 30};
 31
 32var png1B = {
 33        // A 3x3 image, rows are red, green, blue.
 34        // RGB format, transparency=none.
 35
 36        transparency : "none",
 37
 38        frames  : [
 39                {
 40                        width  : 3,    height : 3,
 41
 42                        format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9,
 43
 44                        pixels : [
 45                                255,0,0,  255,0,0, 255,0,0,
 46                                0,255,0,  0,255,0, 0,255,0,
 47                                0,0,255,  0,0,255, 0,0,255,
 48                                ]
 49                }
 50
 51                ],
 52        expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
 53};
 54
 55var png2A = {
 56        // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent.
 57
 58        transparency : null,
 59
 60        frames  : [
 61                {
 62                        width  : 3,    height : 3,
 63
 64                        format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
 65
 66                        pixels : [
 67                                255,0,0,255,  255,0,0,170, 255,0,0,85,
 68                                0,255,0,255,  0,255,0,170, 0,255,0,85,
 69                                0,0,255,255,  0,0,255,170, 0,0,255,85
 70                                ]
 71                }
 72
 73                ],
 74        expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAIElEQVQImSXJMQEAMAwEIUy+yZi8DmVFFBcjycn86GgPJw4O8v9DkkEAAAAASUVORK5CYII="
 75};
 76
 77var png2B = {
 78        // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent,
 79        // but transparency will be ignored.
 80
 81        transparency : "none",
 82
 83        frames  : [
 84                {
 85                        width  : 3,    height : 3,
 86
 87                        format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12,
 88
 89                        pixels : [
 90                                255,0,0,255,  255,0,0,170, 255,0,0,85,
 91                                0,255,0,255,  0,255,0,170, 0,255,0,85,
 92                                0,0,255,255,  0,0,255,170, 0,0,255,85
 93                                ]
 94                }
 95
 96                ],
 97        expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="
 98};
 99
100// Main test entry point.
101function run_test() {
102        dump("Checking png1A...\n")
103        run_test_for(png1A);
104        dump("Checking png1B...\n")
105        run_test_for(png1B);
106        dump("Checking png2A...\n")
107        run_test_for(png2A);
108        dump("Checking png2B...\n")
109        run_test_for(png2B);
110}; 
111
112
113function run_test_for(input) {
114        var encoder, dataURL;
115
116        encoder = encodeImage(input);
117        dataURL = makeDataURL(encoder, "image/png");
118        do_check_eq(dataURL, input.expected);
119
120        encoder = encodeImageAsync(input);
121        dataURL = makeDataURLFromAsync(encoder, "image/png", input.expected);
122};
123
124
125function encodeImage(input) {
126        var encoder = Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance();
127        encoder.QueryInterface(Ci.imgIEncoder);
128
129        var options = "";
130        if (input.transparency) {
131                options += "transparency=" + input.transparency;
132        }
133
134        var frame = input.frames[0];
135        encoder.initFromData(frame.pixels, frame.pixels.length,
136                                frame.width, frame.height, frame.stride,
137                                frame.format, options);
138        return encoder;
139}
140
141function _encodeImageAsyncFactory(frame, options, encoder)
142{
143        function finishEncode() {
144            encoder.addImageFrame(frame.pixels, frame.pixels.length,
145                                  frame.width, frame.height, frame.stride,
146                                  frame.format, options);
147            encoder.endImageEncode();
148        }
149        return finishEncode;
150}
151
152function encodeImageAsync(input)
153{
154        var encoder = Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance();
155        encoder.QueryInterface(Ci.imgIEncoder);
156
157        var options = "";
158        if (input.transparency) {
159                options += "transparency=" + input.transparency;
160        }
161
162        var frame = input.frames[0];
163        encoder.startImageEncode(frame.width, frame.height,
164                                 frame.format, options);
165
166        do_timeout(50, _encodeImageAsyncFactory(frame, options, encoder));
167        return encoder;
168}
169
170
171function makeDataURL(encoder, mimetype) {
172        var rawStream = encoder.QueryInterface(Ci.nsIInputStream);
173
174        var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
175        stream.QueryInterface(Ci.nsIBinaryInputStream);
176
177        stream.setInputStream(rawStream);
178
179        var bytes = stream.readByteArray(stream.available()); // returns int[]
180
181        var base64String = toBase64(bytes);
182
183        return "data:" + mimetype + ";base64," + base64String;
184}
185
186function makeDataURLFromAsync(encoder, mimetype, expected) {
187        do_test_pending();
188        var rawStream = encoder.QueryInterface(Ci.nsIAsyncInputStream);
189
190        var currentThread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread;
191
192        var bytes = [];
193
194        var binarystream = Cc["@mozilla.org/binaryinputstream;1"].createInstance();
195        binarystream.QueryInterface(Ci.nsIBinaryInputStream);
196
197        var asyncReader =
198        {
199            onInputStreamReady: function(stream)
200            {
201                binarystream.setInputStream(stream);
202                var available = 0;
203                try {
204                  available = stream.available();
205                } catch(e) { }
206
207                if (available > 0)
208                {
209                    bytes = bytes.concat(binarystream.readByteArray(available));
210                    stream.asyncWait(this, 0, 0, currentThread);
211                } else {
212                    var base64String = toBase64(bytes);
213                    var dataURL = "data:" + mimetype + ";base64," + base64String;
214                    do_check_eq(dataURL, expected);
215                    do_test_finished();
216                }
217
218            }
219        };
220        rawStream.asyncWait(asyncReader, 0, 0, currentThread);
221}
222
223/* toBase64 copied from extensions/xml-rpc/src/nsXmlRpcClient.js */
224
225/* Convert data (an array of integers) to a Base64 string. */
226const toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +
227    '0123456789+/';
228const base64Pad = '=';
229function toBase64(data) {
230    var result = '';
231    var length = data.length;
232    var i;
233    // Convert every three bytes to 4 ascii characters.
234    for (i = 0; i < (length - 2); i += 3) {
235        result += toBase64Table[data[i] >> 2];
236        result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
237        result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)];
238        result += toBase64Table[data[i+2] & 0x3f];
239    }
240
241    // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
242    if (length%3) {
243        i = length - (length%3);
244        result += toBase64Table[data[i] >> 2];
245        if ((length%3) == 2) {
246            result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
247            result += toBase64Table[(data[i+1] & 0x0f) << 2];
248            result += base64Pad;
249        } else {
250            result += toBase64Table[(data[i] & 0x03) << 4];
251            result += base64Pad + base64Pad;
252        }
253    }
254
255    return result;
256}