@@ -245,57 +245,109 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
245
245
}
246
246
}
247
247
248
- function rescaleImage (pixels , width , height , widthScale , heightScale ) {
249
- var scaledWidth = Math .ceil (width / widthScale );
250
- var scaledHeight = Math .ceil (height / heightScale );
251
-
252
- var itemsSum = new Float32Array (scaledWidth * scaledHeight * 3 );
253
- var itemsCount = new Float32Array (scaledWidth * scaledHeight );
254
- var maxAlphas = new Uint8Array (scaledWidth * scaledHeight );
255
- for (var i = 0 , position = 0 ; i < height ; i ++) {
256
- var lineOffset = (0 | (i / heightScale )) * scaledWidth ;
257
- for (var j = 0 ; j < width ; j ++) {
258
- var countOffset = lineOffset + (0 | (j / widthScale ));
259
- var sumOffset = countOffset * 3 ;
260
- var maxAlpha = maxAlphas [countOffset ];
261
- var currentAlpha = pixels [position + 3 ];
262
- if (maxAlpha < currentAlpha ) {
263
- // lowering total alpha
264
- var scale = 1 - (currentAlpha - maxAlpha ) / 255 ;
265
- itemsSum [sumOffset ] *= scale ;
266
- itemsSum [sumOffset + 1 ] *= scale ;
267
- itemsSum [sumOffset + 2 ] *= scale ;
268
- maxAlphas [countOffset ] = maxAlpha = currentAlpha ;
248
+ function putBinaryImageData (ctx , data , w , h ) {
249
+ var tmpImgData = 'createImageData' in ctx ? ctx .createImageData (w , h ) :
250
+ ctx .getImageData (0 , 0 , w , h );
251
+
252
+ var tmpImgDataPixels = tmpImgData .data ;
253
+ if ('set' in tmpImgDataPixels )
254
+ tmpImgDataPixels .set (data );
255
+ else {
256
+ // Copy over the imageData pixel by pixel.
257
+ for (var i = 0 , ii = tmpImgDataPixels .length ; i < ii ; i ++)
258
+ tmpImgDataPixels [i ] = data [i ];
259
+ }
260
+
261
+ ctx .putImageData (tmpImgData , 0 , 0 );
262
+ }
263
+
264
+ function prescaleImage (pixels , width , height , widthScale , heightScale ) {
265
+ pixels = new Uint8Array (pixels ); // creating a copy
266
+ while (widthScale > 2 || heightScale > 2 ) {
267
+ if (heightScale > 2 ) {
268
+ // scaling image twice vertically
269
+ var rowSize = width * 4 ;
270
+ var k = 0 , l = 0 ;
271
+ for (var i = 0 ; i < height - 1 ; i += 2 ) {
272
+ for (var j = 0 ; j < width ; j ++) {
273
+ var alpha1 = pixels [k + 3 ], alpha2 = pixels [k + 3 + rowSize ];
274
+ if (alpha1 === alpha2 ) {
275
+ pixels [l ] = (pixels [k ] + pixels [k + rowSize ]) >> 1 ;
276
+ pixels [l + 1 ] = (pixels [k + 1 ] + pixels [k + 1 + rowSize ]) >> 1 ;
277
+ pixels [l + 2 ] = (pixels [k + 2 ] + pixels [k + 2 + rowSize ]) >> 1 ;
278
+ pixels [l + 3 ] = alpha1 ;
279
+ } else if (alpha1 < alpha2 ) {
280
+ var d = 256 - alpha2 + alpha1 ;
281
+ pixels [l ] = (pixels [k ] * d + (pixels [k + rowSize ] << 8 )) >> 9 ;
282
+ pixels [l + 1 ] = (pixels [k + 1 ] * d +
283
+ (pixels [k + 1 + rowSize ] << 8 )) >> 9 ;
284
+ pixels [l + 2 ] = (pixels [k + 2 ] * d +
285
+ (pixels [k + 2 + rowSize ] << 8 )) >> 9 ;
286
+ pixels [l + 3 ] = alpha2 ;
287
+ } else {
288
+ var d = 256 - alpha1 + alpha2 ;
289
+ pixels [l ] = ((pixels [k ] << 8 ) + pixels [k + rowSize ] * d ) >> 9 ;
290
+ pixels [l + 1 ] = ((pixels [k + 1 ] << 8 ) +
291
+ pixels [k + 1 + rowSize ] * d ) >> 9 ;
292
+ pixels [l + 2 ] = ((pixels [k + 2 ] << 8 ) +
293
+ pixels [k + 2 + rowSize ] * d ) >> 9 ;
294
+ pixels [l + 3 ] = alpha1 ;
295
+ }
296
+ k += 4 ; l += 4 ;
297
+ }
298
+ k += rowSize ;
269
299
}
270
- if (maxAlpha > currentAlpha ) {
271
- var scale = 1 - (maxAlpha - currentAlpha ) / 255 ;
272
- itemsSum [sumOffset ] += pixels [position ] * scale ;
273
- itemsSum [sumOffset + 1 ] += pixels [position + 1 ] * scale ;
274
- itemsSum [sumOffset + 2 ] += pixels [position + 2 ] * scale ;
275
- itemsCount [countOffset ] += scale ;
276
- } else {
277
- itemsSum [sumOffset ] += pixels [position ];
278
- itemsSum [sumOffset + 1 ] += pixels [position + 1 ];
279
- itemsSum [sumOffset + 2 ] += pixels [position + 2 ];
280
- itemsCount [countOffset ]++;
300
+ if (height & 1 ) {
301
+ for (var i = 0 ; i < rowSize ; i ++) {
302
+ pixels [l ++] = pixels [k ++];
303
+ }
304
+ }
305
+ height = (height + 1 ) >> 1 ;
306
+ heightScale /= 2 ;
307
+ }
308
+ if (widthScale > 2 ) {
309
+ // scaling image twice horizontally
310
+ var k = 0 , l = 0 ;
311
+ for (var i = 0 ; i < height ; i ++) {
312
+ for (var j = 0 ; j < width - 1 ; j += 2 ) {
313
+ var alpha1 = pixels [k + 3 ], alpha2 = pixels [k + 7 ];
314
+ if (alpha1 === alpha2 ) {
315
+ pixels [l ] = (pixels [k ] + pixels [k + 4 ]) >> 1 ;
316
+ pixels [l + 1 ] = (pixels [k + 1 ] + pixels [k + 5 ]) >> 1 ;
317
+ pixels [l + 2 ] = (pixels [k + 2 ] + pixels [k + 6 ]) >> 1 ;
318
+ pixels [l + 3 ] = alpha1 ;
319
+ } else if (alpha1 < alpha2 ) {
320
+ var d = 256 - alpha2 + alpha1 ;
321
+ pixels [l ] = (pixels [k ] * d + (pixels [k + 4 ] << 8 )) >> 9 ;
322
+ pixels [l + 1 ] = (pixels [k + 1 ] * d + (pixels [k + 5 ] << 8 )) >> 9 ;
323
+ pixels [l + 2 ] = (pixels [k + 2 ] * d + (pixels [k + 6 ] << 8 )) >> 9 ;
324
+ pixels [l + 3 ] = alpha2 ;
325
+ } else {
326
+ var d = 256 - alpha1 + alpha2 ;
327
+ pixels [l ] = ((pixels [k ] << 8 ) + pixels [k + 4 ] * d ) >> 9 ;
328
+ pixels [l + 1 ] = ((pixels [k + 1 ] << 8 ) + pixels [k + 5 ] * d ) >> 9 ;
329
+ pixels [l + 2 ] = ((pixels [k + 2 ] << 8 ) + pixels [k + 6 ] * d ) >> 9 ;
330
+ pixels [l + 3 ] = alpha1 ;
331
+ }
332
+ k += 8 ; l += 4 ;
333
+ }
334
+ if (width & 1 ) {
335
+ pixels [l ++] = pixels [k ++];
336
+ pixels [l ++] = pixels [k ++];
337
+ pixels [l ++] = pixels [k ++];
338
+ pixels [l ++] = pixels [k ++];
339
+ }
281
340
}
282
- position += 4 ;
341
+ width = (width + 1 ) >> 1 ;
342
+ widthScale /= 2 ;
283
343
}
284
344
}
285
- var tmpCanvas = createScratchCanvas (scaledWidth , scaledHeight );
345
+
346
+ var tmpCanvas = createScratchCanvas (width , height );
286
347
var tmpCtx = tmpCanvas .getContext ('2d' );
287
- var imgData = tmpCtx .getImageData (0 , 0 , scaledWidth , scaledHeight );
288
- pixels = imgData .data ;
289
- var j = 0 , q = 0 ;
290
- for (var i = 0 , ii = scaledWidth * scaledHeight ; i < ii ; i ++) {
291
- var count = itemsCount [i ];
292
- pixels [j ] = itemsSum [q ++] / count ;
293
- pixels [j + 1 ] = itemsSum [q ++] / count ;
294
- pixels [j + 2 ] = itemsSum [q ++] / count ;
295
- pixels [j + 3 ] = maxAlphas [i ];
296
- j += 4 ;
297
- }
298
- tmpCtx .putImageData (imgData , 0 , 0 );
348
+ putBinaryImageData (tmpCtx , pixels .subarray (0 , width * height * 4 ),
349
+ width , height );
350
+
299
351
return tmpCanvas ;
300
352
}
301
353
@@ -1314,19 +1366,19 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
1314
1366
var tmpCanvas = createScratchCanvas (width , height );
1315
1367
var tmpCtx = tmpCanvas .getContext ('2d' );
1316
1368
1317
- if (widthScale >= 2 || heightScale >= 2 ) {
1369
+ if (widthScale > 2 || heightScale > 2 ) {
1318
1370
// canvas does not resize well large images to small -- using simple
1319
1371
// algorithm to perform pre-scaling
1320
- tmpCanvas = rescaleImage (imgData .data ,
1372
+ tmpCanvas = prescaleImage (imgData .data ,
1321
1373
width , height ,
1322
1374
widthScale , heightScale );
1323
- ctx .scale ( widthScale , heightScale );
1324
- ctx . drawImage ( tmpCanvas , 0 , -height / heightScale );
1375
+ ctx .drawImage ( tmpCanvas , 0 , 0 , tmpCanvas . width , tmpCanvas . height ,
1376
+ 0 , -height , width , height );
1325
1377
} else {
1326
1378
if (typeof ImageData !== 'undefined' && imgData instanceof ImageData ) {
1327
1379
tmpCtx .putImageData (imgData , 0 , 0 );
1328
1380
} else {
1329
- this . putBinaryImageData (tmpCtx , imgData );
1381
+ putBinaryImageData (tmpCtx , imgData . data , width , height );
1330
1382
}
1331
1383
ctx .drawImage (tmpCanvas , 0 , -height );
1332
1384
}
@@ -1341,7 +1393,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
1341
1393
1342
1394
var tmpCanvas = createScratchCanvas (w , h );
1343
1395
var tmpCtx = tmpCanvas .getContext ('2d' );
1344
- this . putBinaryImageData (tmpCtx , imgData );
1396
+ putBinaryImageData (tmpCtx , imgData . data , w , h );
1345
1397
1346
1398
for (var i = 0 , ii = map .length ; i < ii ; i ++) {
1347
1399
var entry = map [i ];
@@ -1354,25 +1406,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
1354
1406
}
1355
1407
},
1356
1408
1357
- putBinaryImageData : function CanvasGraphics_putBinaryImageData (ctx ,
1358
- imgData ) {
1359
- var w = imgData .width , h = imgData .height ;
1360
- var tmpImgData = 'createImageData' in ctx ? ctx .createImageData (w , h ) :
1361
- ctx .getImageData (0 , 0 , w , h );
1362
-
1363
- var tmpImgDataPixels = tmpImgData .data ;
1364
- var data = imgData .data ;
1365
- if ('set' in tmpImgDataPixels )
1366
- tmpImgDataPixels .set (data );
1367
- else {
1368
- // Copy over the imageData pixel by pixel.
1369
- for (var i = 0 , ii = tmpImgDataPixels .length ; i < ii ; i ++)
1370
- tmpImgDataPixels [i ] = data [i ];
1371
- }
1372
-
1373
- ctx .putImageData (tmpImgData , 0 , 0 );
1374
- },
1375
-
1376
1409
// Marked content
1377
1410
1378
1411
markPoint : function CanvasGraphics_markPoint (tag ) {
0 commit comments