Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webgl / src / sdk / tests / conformance / textures / gl-teximage.html
1 <!--
2
3 /*
4 ** Copyright (c) 2012 The Khronos Group Inc.
5 **
6 ** Permission is hereby granted, free of charge, to any person obtaining a
7 ** copy of this software and/or associated documentation files (the
8 ** "Materials"), to deal in the Materials without restriction, including
9 ** without limitation the rights to use, copy, modify, merge, publish,
10 ** distribute, sublicense, and/or sell copies of the Materials, and to
11 ** permit persons to whom the Materials are furnished to do so, subject to
12 ** the following conditions:
13 **
14 ** The above copyright notice and this permission notice shall be included
15 ** in all copies or substantial portions of the Materials.
16 **
17 ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
24 */
25
26 -->
27
28 <!DOCTYPE html>
29 <html>
30 <head>
31 <meta charset="utf-8">
32 <title>WebGL texImage2D conformance test.</title>
33 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
34 <script src="../../resources/js-test-pre.js"></script>
35 <script src="../resources/webgl-test-utils.js"> </script>
36 </head>
37 <body>
38 <canvas id="example" width="256" height="16" style="width: 256px; height: 48px;"></canvas>
39 <div id="description"></div>
40 <div id="console"></div>
41 <script>
42 "use strict";
43 enableJSTestPreVerboseLogging();
44 description("Test texImage2D conversions.");
45 var wtu = WebGLTestUtils;
46 var gl = wtu.create3DContext("example");
47 gl.disable(gl.DITHER);
48 var program = wtu.setupTexturedQuad(gl);
49 var successfullyParsed;
50
51 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
52
53 var imgURLs = [
54   '../resources/1-channel.jpg',
55   '../resources/gray-ramp-256-with-128-alpha.png',
56   '../resources/gray-ramp-256.png',
57   '../resources/gray-ramp-default-gamma.png',
58   '../resources/gray-ramp-gamma0.1.png',
59   '../resources/gray-ramp-gamma1.0.png',
60   '../resources/gray-ramp-gamma2.0.png',
61   '../resources/gray-ramp-gamma4.0.png',
62   '../resources/gray-ramp-gamma9.0.png',
63   '../resources/gray-ramp.png',
64   '../resources/zero-alpha.png',
65   '../resources/3x3.png',
66   '../resources/blue-1x1.jpg',
67   '../resources/red-indexed.png',
68   '../resources/transparent-on-left-indexed.png',
69   '../resources/green-2x2-16bit.png',
70   '../resources/small-square-with-colorspin-profile.jpg',
71   '../resources/small-square-with-colorspin-profile.png',
72   '../resources/small-square-with-cie-rgb-profile.png',
73   '../resources/small-square-with-colormatch-profile.png',
74   '../resources/small-square-with-e-srgb-profile.png',
75   '../resources/small-square-with-smpte-c-profile.png',
76   '../resources/small-square-with-srgb-iec61966-2.1-profile.png'];
77
78
79 wtu.loadImagesAsync(imgURLs, runTests);
80
81 function runTests(imgs) {
82   var loc = gl.getUniformLocation(program, "tex");
83   gl.uniform1i(loc, 0);
84
85   gl.disable(gl.BLEND);
86   gl.disable(gl.DEPTH_TEST);
87
88   var width = gl.canvas.width;
89   var height = gl.canvas.height;
90
91   function checkPixel(buf, x, y, color) {
92     var off = (y * width + x) * 4;
93     var msg = "pixel " + x + ", " + y + " should be " +
94               color[0] + ", " +
95               color[1] + ", " +
96               color[2] + ", " +
97               color[3] + " was " +
98               buf[off + 0] + ", " +
99               buf[off + 1] + ", " +
100               buf[off + 2] + ", " +
101               buf[off + 3];
102
103     for (var ii = 0; ii < 4; ++ii) {
104       if (buf[off + ii] != color[ii]) {
105         testFailed(msg);
106         return;
107       }
108     }
109     testPassed(msg);
110   }
111
112   function checkPixelRange(buf, x, y, color, allowedRange) {
113     var off = (y * width + x) * 4;
114     var msg = "pixel " + x + ", " + y + " should be within " +
115               allowedRange + " units of " +
116               color[0] + ", " +
117               color[1] + ", " +
118               color[2] + ", " +
119               color[3];
120     var subMsg = " was " +
121               buf[off + 0] + ", " +
122               buf[off + 1] + ", " +
123               buf[off + 2] + ", " +
124               buf[off + 3];
125     // When running in WebKit's test harness, we don't want to print the
126     // pixel value when the test passes, because different machines might
127     // have different results and we record the text output.
128     var inDumpRenderTree = window.layoutTestController;
129     for (var ii = 0; ii < 4; ++ii) {
130       if (Math.abs(buf[off + ii] - color[ii]) > allowedRange) {
131         testFailed(msg + subMsg);
132         return;
133       }
134     }
135     testPassed(msg + (inDumpRenderTree ? "" : subMsg));
136   }
137
138   var tex = gl.createTexture();
139   gl.bindTexture(gl.TEXTURE_2D, tex);
140   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
141   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
142   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
143   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
144
145   var buf = new Uint8Array(width * height * 4);
146
147   debug("");
148   debug("check pixels are NOT pre-multiplied");
149   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
150                 imgs['../resources/zero-alpha.png']);
151   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
152   wtu.clearAndDrawUnitQuad(gl);
153   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
154
155   var left = 0;
156   var middle = Math.floor(width / 2);
157   var right = width - 1;
158   var bottom = 0;
159   var center = Math.floor(height / 2);
160   var top = height - 1;
161   checkPixel(buf, left,   top,    [  0,   0,   0, 255]);
162   checkPixel(buf, middle, top,    [255,   0, 255, 255]);
163   checkPixel(buf, right,  top,    [  0,   0, 255, 255]);
164   checkPixel(buf, left,   center, [128, 128, 128, 255]);
165   checkPixel(buf, middle, center, [255, 255, 255, 255]);
166   checkPixel(buf, right,  center, [  0, 255, 255, 255]);
167   checkPixel(buf, left,   bottom, [255,   0,   0, 255]);
168   checkPixel(buf, middle, bottom, [255, 255,   0, 255]);
169   checkPixel(buf, right,  bottom, [  0, 255,   0, 255]);
170
171   debug("");
172   debug("check quantization");
173   var quantInfo = [
174     {format: gl.RGBA, type: gl.UNSIGNED_BYTE,          counts: [256, 256, 256, 256]},
175     {format: gl.RGBA, type: gl.UNSIGNED_SHORT_4_4_4_4, counts: [ 16,  16,  16,  16]},
176     {format: gl.RGB,  type: gl.UNSIGNED_SHORT_5_6_5,   counts: [ 32,  64,  32,   1]},
177     {format: gl.RGBA, type: gl.UNSIGNED_SHORT_5_5_5_1, counts: [ 32,  32,  32,   2]}];
178   for (var qq = 0; qq < quantInfo.length; ++qq) {
179     var info = quantInfo[qq];
180     gl.texImage2D(
181         gl.TEXTURE_2D, 0, info.format, info.format, info.type,
182         imgs['../resources/gray-ramp-256.png']);
183     wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
184     wtu.clearAndDrawUnitQuad(gl);
185     gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
186     var counts = [{ }, { }, { }, { }];
187     var numUniqueValues = [0, 0, 0, 0];
188     // Count the number of unique values in each channel.
189     for (var ii = 0; ii < width * height * 4; ii += 4) {
190       for (var jj = 0; jj < 4; ++jj) {
191         var v = buf[ii + jj];
192         if (!counts[jj][v]) {
193           counts[jj][v] = 1;
194           ++numUniqueValues[jj];
195         } else {
196           ++counts[jj][v];
197         }
198       }
199     }
200     for (var ii = 0; ii < 4; ++ii) {
201       assertMsg(numUniqueValues[ii] == info.counts[ii],
202                 "There should be " + info.counts[ii] +
203                 " unique values in channel " + ii + ". Found " +
204                 numUniqueValues[ii]);
205     }
206   }
207
208   debug("");
209   debug("Check that gamma settings don't effect 8bit pngs");
210   gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
211   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
212                 imgs['../resources/gray-ramp-default-gamma.png']);
213   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
214   wtu.clearAndDrawUnitQuad(gl);
215   var ref = new Uint8Array(width * height * 4);
216   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, ref);
217
218   var gammaImages = [
219     '../resources/gray-ramp-gamma0.1.png',
220     '../resources/gray-ramp-gamma1.0.png',
221     '../resources/gray-ramp-gamma2.0.png',
222     '../resources/gray-ramp-gamma4.0.png',
223     '../resources/gray-ramp-gamma9.0.png'];
224   for (var ii = 0; ii < gammaImages.length; ++ii) {
225     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
226                   imgs[gammaImages[ii]]);
227     wtu.clearAndDrawUnitQuad(gl);
228     gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
229     var same = true;
230     for (var jj = 0; jj < width * height * 4; ++jj) {
231       if (buf[jj] != ref[jj]) {
232         same = false;
233         break;
234       }
235     }
236     assertMsg(same, "pixels should be same regardless of gamma settings.");
237   }
238
239   debug("");
240   debug("check pixels are UN pre-multiplied");
241   for (var ii = 0; ii < 2; ++ii) {
242     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
243     if (ii == 0) {
244       var canvas2d = document.createElement("canvas");
245       canvas2d.width = 256;
246       canvas2d.height = 1;
247       var ctx = canvas2d.getContext("2d");
248       ctx.drawImage(imgs['../resources/gray-ramp-256-with-128-alpha.png'], 0, 0);
249       gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, canvas2d);
250     } else {
251       gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
252                     imgs['../resources/gray-ramp-256-with-128-alpha.png']);
253     }
254     wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
255     wtu.clearAndDrawUnitQuad(gl);
256     var buf = new Uint8Array(width * height * 4);
257     gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
258     var lt128Count = [0, 0, 0];
259     var ge128Count = [0, 0, 0];
260     for (var jj = 0; jj < width; ++jj) {
261       var off = jj * 4;
262       for (var cc = 0; cc < 3; ++cc) {
263         if (buf[off + cc] < 128) {
264           ++lt128Count[cc];
265         } else {
266           ++ge128Count[cc];
267         }
268       }
269     }
270     // Not sure the exact count here because gamma does effect drawing into the
271     // canvas but it should be close to 50% so I'll pass 45%
272     for (var jj = 0; jj < 3; ++jj) {
273       assertMsg(ge128Count[jj] > 256 * 0.45,
274                 "Half the pixels in channel " + jj +
275                 " should be >= 128,128,128. found " +
276                 ((ge128Count[jj] / 256) * 100).toFixed() + "%");
277       assertMsg(lt128Count[jj] > 256 * 0.45,
278                 "Half the pixels in channel " + jj +
279                 " should be < 128,128,128. found " +
280                 ((lt128Count[jj] / 256) * 100).toFixed() + "%");
281     }
282   }
283
284   debug("");
285   debug("check canvas pixels are UN pre-multiplied");
286   var canvas2d = document.createElement("canvas");
287   canvas2d.width = 1;
288   canvas2d.height = 1;
289   var ctx = canvas2d.getContext("2d");
290   ctx.fillStyle ="rgba(255,255,255,0.5)";
291   ctx.fillRect(0, 0, 256, 1);
292   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
293   wtu.clearAndDrawUnitQuad(gl);
294   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
295   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
296   checkPixelRange(buf, 0, 0, [255, 255, 255, 127], 4);
297
298   debug("");
299   debug("check canvas pixels are pre-multiplied");
300   gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
301   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
302   wtu.clearAndDrawUnitQuad(gl);
303   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
304   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
305   checkPixelRange(buf, 0, 0, [127, 127, 127, 127], 4);
306
307
308   debug("");
309   debug("check pixels are pre-multiplied");
310   gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
311   // TODO(gman): use different texture that won't pass on failure
312   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
313                 imgs['../resources/zero-alpha.png']);
314   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
315   wtu.clearAndDrawUnitQuad(gl);
316   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
317
318   var same = true;
319   for (var jj = 0; jj < width * height * 4; ++jj) {
320     if (buf[jj] != 0) {
321       same = false;
322       break;
323     }
324   }
325   assertMsg(same, "pixels should all be 0.");
326
327   debug("");
328   debug("check pixels are flipped");
329   gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
330   gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
331   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
332                 imgs['../resources/3x3.png']);
333   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
334   wtu.clearAndDrawUnitQuad(gl);
335   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
336
337   checkPixel(buf, left,   top,    [255,   0,   0, 255]);
338   checkPixel(buf, middle, top,    [255, 255,   0, 255]);
339   checkPixel(buf, right,  top,    [255,   0,   0, 255]);
340   checkPixel(buf, left,   center, [255,   0, 255, 255]);
341   checkPixel(buf, middle, center, [255,   0,   0, 255]);
342   checkPixel(buf, right,  center, [  0, 255,   0, 255]);
343   checkPixel(buf, left,   bottom, [  0,   0,   0, 255]);
344   checkPixel(buf, middle, bottom, [  0,   0, 255, 255]);
345   checkPixel(buf, right,  bottom, [255,   0,   0, 255]);
346
347   debug("");
348   debug("check uploading of images with no alpha channel works");
349   gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
350   gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
351   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
352                 imgs['../resources/blue-1x1.jpg']);
353   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
354   wtu.clearAndDrawUnitQuad(gl);
355   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
356   checkPixelRange(buf, middle, center, [   0,   0, 255, 255], 10);
357   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
358
359   debug("");
360   debug("check uploading of 16-bit images");
361   gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
362   gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
363   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
364                 imgs['../resources/green-2x2-16bit.png']);
365   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
366   wtu.clearAndDrawUnitQuad(gl);
367   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
368   checkPixelRange(buf, middle, center, [   15, 121,   0, 255], 10);
369   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
370
371   debug("");
372   debug("check uploading of images with ICC profiles");
373   gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
374   gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
375   gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
376
377   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
378                 imgs['../resources/small-square-with-colorspin-profile.jpg']);
379   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
380   wtu.clearAndDrawUnitQuad(gl);
381   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
382   // The image is red.  However, if we ignore the color profile, it is blue.
383   checkPixelRange(buf, middle, center, [ 0, 0, 255, 255], 10);
384
385   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
386                 imgs['../resources/small-square-with-colorspin-profile.png']);
387   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
388   wtu.clearAndDrawUnitQuad(gl);
389   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
390   // The image is red.  However, if we ignore the color profile, it is blue.
391   checkPixelRange(buf, middle, center, [ 0, 0, 255, 255], 10);
392
393   var iccPNGs = [
394     '../resources/small-square-with-cie-rgb-profile.png',
395     '../resources/small-square-with-colormatch-profile.png',
396     '../resources/small-square-with-e-srgb-profile.png',
397     '../resources/small-square-with-smpte-c-profile.png',
398     '../resources/small-square-with-srgb-iec61966-2.1-profile.png'];
399   for (var ii = 0; ii < iccPNGs.length; ++ii) {
400     var buf2 = new Uint8Array(width * height * 4);
401     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
402                   imgs[iccPNGs[ii]]);
403     wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
404     wtu.clearAndDrawUnitQuad(gl);
405     gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf2);
406     wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
407     var same = true;
408     for (var jj = 0; jj < buf.length; ++jj) {
409       if (buf[jj] != buf2[jj]) {
410         same = false;
411         break;
412       }
413     }
414     assertMsg(same, "uploading PNGs with same data but various ICC profiles should generate the same results");
415   }
416
417   debug("");
418   debug("check uploading of indexed PNG images");
419   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
420                 imgs['../resources/red-indexed.png']);
421   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
422   wtu.clearAndDrawUnitQuad(gl);
423   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
424   // The image should be red.
425   checkPixelRange(buf, middle, center, [ 255, 0, 0, 255 ], 10);
426
427   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
428   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
429                 imgs['../resources/transparent-on-left-indexed.png']);
430   wtu.clearAndDrawUnitQuad(gl);
431   wtu.checkCanvasRect(gl, 0, 0, 128, 16, [255, 0, 255, 0], "should be transparent purple");
432   wtu.checkCanvasRect(gl, 128, 0,128, 16, [255, 255, 0, 255], "should be yellow");
433
434   debug("");
435   debug("check uploading of 1-channel JPG images");
436   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
437                 imgs['../resources/1-channel.jpg']);
438   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
439   wtu.clearAndDrawUnitQuad(gl);
440   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
441   // The image should be gray.
442   checkPixelRange(buf, middle, center, [ 128, 128, 128, 255 ], 28);
443
444   debug("")
445   debug("check calling texImage2D with NULL clears the texture");
446   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB,
447                 imgs['../resources/red-indexed.png'].width,
448                 imgs['../resources/red-indexed.png'].height,
449                 0, gl.RGB, gl.UNSIGNED_BYTE, null);
450   wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
451   wtu.clearAndDrawUnitQuad(gl);
452   gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
453   // The image should be white.
454   checkPixelRange(buf, middle, center, [ 0, 0, 0, 255 ], 10);
455
456   debug("");
457   successfullyParsed = true;
458   shouldBeTrue("successfullyParsed");
459   debug('<br /><span class="pass">TEST COMPLETE</span>');
460   notifyFinishedToHarness();
461 }
462 </script>
463 </body>
464 </html>
465