Leptonica  1.73
Image processing and image analysis suite
scale2.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
98 #include <string.h>
99 #include "allheaders.h"
100 
101 static void scaleToGray2Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
102  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
103  l_uint32 *sumtab, l_uint8 *valtab);
104 static l_uint32 *makeSumTabSG2(void);
105 static l_uint8 *makeValTabSG2(void);
106 static void scaleToGray3Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
107  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
108  l_uint32 *sumtab, l_uint8 *valtab);
109 static l_uint32 *makeSumTabSG3(void);
110 static l_uint8 *makeValTabSG3(void);
111 static void scaleToGray4Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
112  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
113  l_uint32 *sumtab, l_uint8 *valtab);
114 static l_uint32 *makeSumTabSG4(void);
115 static l_uint8 *makeValTabSG4(void);
116 static void scaleToGray6Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
117  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
118  l_int32 *tab8, l_uint8 *valtab);
119 static l_uint8 *makeValTabSG6(void);
120 static void scaleToGray8Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
121  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
122  l_int32 *tab8, l_uint8 *valtab);
123 static l_uint8 *makeValTabSG8(void);
124 static void scaleToGray16Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
125  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
126  l_int32 *tab8);
127 static l_int32 scaleMipmapLow(l_uint32 *datad, l_int32 wd, l_int32 hd,
128  l_int32 wpld, l_uint32 *datas1, l_int32 wpls1,
129  l_uint32 *datas2, l_int32 wpls2, l_float32 red);
130 
131 extern l_float32 AlphaMaskBorderVals[2];
132 
133 
134 /*------------------------------------------------------------------*
135  * Scale-to-gray (1 bpp --> 8 bpp; arbitrary downscaling) *
136  *------------------------------------------------------------------*/
203 PIX *
205  l_float32 scalefactor)
206 {
207 l_int32 w, h, minsrc, mindest;
208 l_float32 mag, red;
209 PIX *pixt, *pixd;
210 
211  PROCNAME("pixScaleToGray");
212 
213  if (!pixs)
214  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
215  if (pixGetDepth(pixs) != 1)
216  return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
217  if (scalefactor <= 0.0)
218  return (PIX *)ERROR_PTR("scalefactor <= 0.0", procName, NULL);
219  if (scalefactor >= 1.0)
220  return (PIX *)ERROR_PTR("scalefactor >= 1.0", procName, NULL);
221  pixGetDimensions(pixs, &w, &h, NULL);
222  minsrc = L_MIN(w, h);
223  mindest = (l_int32)((l_float32)minsrc * scalefactor);
224  if (mindest < 2)
225  return (PIX *)ERROR_PTR("scalefactor too small", procName, NULL);
226 
227  if (scalefactor > 0.5) { /* see note (5) */
228  mag = 2.0 * scalefactor; /* will be < 2.0 */
229 /* fprintf(stderr, "2x with mag %7.3f\n", mag); */
230  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
231  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
232  pixd = pixScaleToGray2(pixt);
233  } else if (scalefactor == 0.5) {
234  return pixd = pixScaleToGray2(pixs);
235  } else if (scalefactor > 0.33333) { /* see note (5) */
236  mag = 3.0 * scalefactor; /* will be < 1.5 */
237 /* fprintf(stderr, "3x with mag %7.3f\n", mag); */
238  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
239  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
240  pixd = pixScaleToGray3(pixt);
241  } else if (scalefactor > 0.25) { /* see note (5) */
242  mag = 4.0 * scalefactor; /* will be < 1.3333 */
243 /* fprintf(stderr, "4x with mag %7.3f\n", mag); */
244  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
245  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
246  pixd = pixScaleToGray4(pixt);
247  } else if (scalefactor == 0.25) {
248  return pixd = pixScaleToGray4(pixs);
249  } else if (scalefactor > 0.16667) { /* see note (5) */
250  mag = 6.0 * scalefactor; /* will be < 1.5 */
251 /* fprintf(stderr, "6x with mag %7.3f\n", mag); */
252  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
253  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
254  pixd = pixScaleToGray6(pixt);
255  } else if (scalefactor == 0.16667) {
256  return pixd = pixScaleToGray6(pixs);
257  } else if (scalefactor > 0.125) { /* see note (5) */
258  mag = 8.0 * scalefactor; /* will be < 1.3333 */
259 /* fprintf(stderr, "8x with mag %7.3f\n", mag); */
260  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
261  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
262  pixd = pixScaleToGray8(pixt);
263  } else if (scalefactor == 0.125) {
264  return pixd = pixScaleToGray8(pixs);
265  } else if (scalefactor > 0.0625) { /* see note (6) */
266  red = 8.0 * scalefactor; /* will be > 0.5 */
267 /* fprintf(stderr, "8x with red %7.3f\n", red); */
268  if ((pixt = pixScaleBinary(pixs, red, red)) == NULL)
269  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
270  pixd = pixScaleToGray8(pixt);
271  } else if (scalefactor == 0.0625) {
272  return pixd = pixScaleToGray16(pixs);
273  } else { /* see note (7) */
274  red = 16.0 * scalefactor; /* will be <= 1.0 */
275 /* fprintf(stderr, "16x with red %7.3f\n", red); */
276  if ((pixt = pixScaleToGray16(pixs)) == NULL)
277  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
278  if (red < 0.7)
279  pixd = pixScaleSmooth(pixt, red, red); /* see note (3) */
280  else
281  pixd = pixScaleGrayLI(pixt, red, red); /* see note (2) */
282  }
283 
284  pixDestroy(&pixt);
285  if (!pixd)
286  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
287  pixCopyInputFormat(pixd, pixs);
288  return pixd;
289 }
290 
291 
314 PIX *
316  l_float32 scalefactor)
317 {
318 l_int32 w, h, minsrc, mindest;
319 l_float32 eps, factor;
320 PIX *pixt, *pixd;
321 
322  PROCNAME("pixScaleToGrayFast");
323 
324  if (!pixs)
325  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
326  if (pixGetDepth(pixs) != 1)
327  return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
328  if (scalefactor <= 0.0)
329  return (PIX *)ERROR_PTR("scalefactor <= 0.0", procName, NULL);
330  if (scalefactor >= 1.0)
331  return (PIX *)ERROR_PTR("scalefactor >= 1.0", procName, NULL);
332  pixGetDimensions(pixs, &w, &h, NULL);
333  minsrc = L_MIN(w, h);
334  mindest = (l_int32)((l_float32)minsrc * scalefactor);
335  if (mindest < 2)
336  return (PIX *)ERROR_PTR("scalefactor too small", procName, NULL);
337  eps = 0.0001;
338 
339  /* Handle the special cases */
340  if (scalefactor > 0.5 - eps && scalefactor < 0.5 + eps)
341  return pixScaleToGray2(pixs);
342  else if (scalefactor > 0.33333 - eps && scalefactor < 0.33333 + eps)
343  return pixScaleToGray3(pixs);
344  else if (scalefactor > 0.25 - eps && scalefactor < 0.25 + eps)
345  return pixScaleToGray4(pixs);
346  else if (scalefactor > 0.16666 - eps && scalefactor < 0.16666 + eps)
347  return pixScaleToGray6(pixs);
348  else if (scalefactor > 0.125 - eps && scalefactor < 0.125 + eps)
349  return pixScaleToGray8(pixs);
350  else if (scalefactor > 0.0625 - eps && scalefactor < 0.0625 + eps)
351  return pixScaleToGray16(pixs);
352 
353  if (scalefactor > 0.0625) { /* scale binary first */
354  factor = 2.0 * scalefactor;
355  if ((pixt = pixScaleBinary(pixs, factor, factor)) == NULL)
356  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
357  pixd = pixScaleToGray2(pixt);
358  } else { /* scalefactor < 0.0625; scale-to-gray first */
359  factor = 16.0 * scalefactor; /* will be < 1.0 */
360  if ((pixt = pixScaleToGray16(pixs)) == NULL)
361  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
362  if (factor < 0.7)
363  pixd = pixScaleSmooth(pixt, factor, factor);
364  else
365  pixd = pixScaleGrayLI(pixt, factor, factor);
366  }
367  pixDestroy(&pixt);
368  if (!pixd)
369  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
370  pixCopyInputFormat(pixd, pixs);
371  return pixd;
372 }
373 
374 
375 /*-----------------------------------------------------------------------*
376  * Scale-to-gray (1 bpp --> 8 bpp; integer downscaling) *
377  *-----------------------------------------------------------------------*/
385 PIX *
387 {
388 l_uint8 *valtab;
389 l_int32 ws, hs, wd, hd;
390 l_int32 wpld, wpls;
391 l_uint32 *sumtab;
392 l_uint32 *datas, *datad;
393 PIX *pixd;
394 
395  PROCNAME("pixScaleToGray2");
396 
397  if (!pixs)
398  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
399  if (pixGetDepth(pixs) != 1)
400  return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, NULL);
401 
402  pixGetDimensions(pixs, &ws, &hs, NULL);
403  wd = ws / 2;
404  hd = hs / 2;
405  if (wd == 0 || hd == 0)
406  return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
407 
408  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
409  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
410  pixCopyInputFormat(pixd, pixs);
411  pixCopyResolution(pixd, pixs);
412  pixScaleResolution(pixd, 0.5, 0.5);
413  datas = pixGetData(pixs);
414  datad = pixGetData(pixd);
415  wpls = pixGetWpl(pixs);
416  wpld = pixGetWpl(pixd);
417 
418  sumtab = makeSumTabSG2();
419  valtab = makeValTabSG2();
420  scaleToGray2Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
421  LEPT_FREE(sumtab);
422  LEPT_FREE(valtab);
423  return pixd;
424 }
425 
426 
442 PIX *
444 {
445 l_uint8 *valtab;
446 l_int32 ws, hs, wd, hd;
447 l_int32 wpld, wpls;
448 l_uint32 *sumtab;
449 l_uint32 *datas, *datad;
450 PIX *pixd;
451 
452  PROCNAME("pixScaleToGray3");
453 
454  if (!pixs)
455  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
456  if (pixGetDepth(pixs) != 1)
457  return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
458 
459  pixGetDimensions(pixs, &ws, &hs, NULL);
460  wd = (ws / 3) & 0xfffffff8; /* truncate to factor of 8 */
461  hd = hs / 3;
462  if (wd == 0 || hd == 0)
463  return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
464 
465  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
466  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
467  pixCopyInputFormat(pixd, pixs);
468  pixCopyResolution(pixd, pixs);
469  pixScaleResolution(pixd, 0.33333, 0.33333);
470  datas = pixGetData(pixs);
471  datad = pixGetData(pixd);
472  wpls = pixGetWpl(pixs);
473  wpld = pixGetWpl(pixd);
474 
475  sumtab = makeSumTabSG3();
476  valtab = makeValTabSG3();
477  scaleToGray3Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
478  LEPT_FREE(sumtab);
479  LEPT_FREE(valtab);
480  return pixd;
481 }
482 
483 
496 PIX *
498 {
499 l_uint8 *valtab;
500 l_int32 ws, hs, wd, hd;
501 l_int32 wpld, wpls;
502 l_uint32 *sumtab;
503 l_uint32 *datas, *datad;
504 PIX *pixd;
505 
506  PROCNAME("pixScaleToGray4");
507 
508  if (!pixs)
509  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
510  if (pixGetDepth(pixs) != 1)
511  return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, NULL);
512 
513  pixGetDimensions(pixs, &ws, &hs, NULL);
514  wd = (ws / 4) & 0xfffffffe; /* truncate to factor of 2 */
515  hd = hs / 4;
516  if (wd == 0 || hd == 0)
517  return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
518 
519  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
520  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
521  pixCopyInputFormat(pixd, pixs);
522  pixCopyResolution(pixd, pixs);
523  pixScaleResolution(pixd, 0.25, 0.25);
524  datas = pixGetData(pixs);
525  datad = pixGetData(pixd);
526  wpls = pixGetWpl(pixs);
527  wpld = pixGetWpl(pixd);
528 
529  sumtab = makeSumTabSG4();
530  valtab = makeValTabSG4();
531  scaleToGray4Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
532  LEPT_FREE(sumtab);
533  LEPT_FREE(valtab);
534  return pixd;
535 }
536 
537 
538 
551 PIX *
553 {
554 l_uint8 *valtab;
555 l_int32 ws, hs, wd, hd, wpld, wpls;
556 l_int32 *tab8;
557 l_uint32 *datas, *datad;
558 PIX *pixd;
559 
560  PROCNAME("pixScaleToGray6");
561 
562  if (!pixs)
563  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
564  if (pixGetDepth(pixs) != 1)
565  return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
566 
567  pixGetDimensions(pixs, &ws, &hs, NULL);
568  wd = (ws / 6) & 0xfffffff8; /* truncate to factor of 8 */
569  hd = hs / 6;
570  if (wd == 0 || hd == 0)
571  return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
572 
573  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
574  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
575  pixCopyInputFormat(pixd, pixs);
576  pixCopyResolution(pixd, pixs);
577  pixScaleResolution(pixd, 0.16667, 0.16667);
578  datas = pixGetData(pixs);
579  datad = pixGetData(pixd);
580  wpls = pixGetWpl(pixs);
581  wpld = pixGetWpl(pixd);
582 
583  tab8 = makePixelSumTab8();
584  valtab = makeValTabSG6();
585  scaleToGray6Low(datad, wd, hd, wpld, datas, wpls, tab8, valtab);
586  LEPT_FREE(tab8);
587  LEPT_FREE(valtab);
588  return pixd;
589 }
590 
591 
599 PIX *
601 {
602 l_uint8 *valtab;
603 l_int32 ws, hs, wd, hd;
604 l_int32 wpld, wpls;
605 l_int32 *tab8;
606 l_uint32 *datas, *datad;
607 PIX *pixd;
608 
609  PROCNAME("pixScaleToGray8");
610 
611  if (!pixs)
612  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
613  if (pixGetDepth(pixs) != 1)
614  return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, NULL);
615 
616  pixGetDimensions(pixs, &ws, &hs, NULL);
617  wd = ws / 8; /* truncate to nearest dest byte */
618  hd = hs / 8;
619  if (wd == 0 || hd == 0)
620  return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
621 
622  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
623  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
624  pixCopyInputFormat(pixd, pixs);
625  pixCopyResolution(pixd, pixs);
626  pixScaleResolution(pixd, 0.125, 0.125);
627  datas = pixGetData(pixs);
628  datad = pixGetData(pixd);
629  wpls = pixGetWpl(pixs);
630  wpld = pixGetWpl(pixd);
631 
632  tab8 = makePixelSumTab8();
633  valtab = makeValTabSG8();
634  scaleToGray8Low(datad, wd, hd, wpld, datas, wpls, tab8, valtab);
635  LEPT_FREE(tab8);
636  LEPT_FREE(valtab);
637  return pixd;
638 }
639 
640 
648 PIX *
650 {
651 l_int32 ws, hs, wd, hd;
652 l_int32 wpld, wpls;
653 l_int32 *tab8;
654 l_uint32 *datas, *datad;
655 PIX *pixd;
656 
657  PROCNAME("pixScaleToGray16");
658 
659  if (!pixs)
660  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
661  if (pixGetDepth(pixs) != 1)
662  return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, NULL);
663 
664  pixGetDimensions(pixs, &ws, &hs, NULL);
665  wd = ws / 16;
666  hd = hs / 16;
667  if (wd == 0 || hd == 0)
668  return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
669 
670  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
671  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
672  pixCopyInputFormat(pixd, pixs);
673  pixCopyResolution(pixd, pixs);
674  pixScaleResolution(pixd, 0.0625, 0.0625);
675  datas = pixGetData(pixs);
676  datad = pixGetData(pixd);
677  wpls = pixGetWpl(pixs);
678  wpld = pixGetWpl(pixd);
679 
680  tab8 = makePixelSumTab8();
681  scaleToGray16Low(datad, wd, hd, wpld, datas, wpls, tab8);
682  LEPT_FREE(tab8);
683  return pixd;
684 }
685 
686 
687 /*------------------------------------------------------------------*
688  * Scale-to-gray mipmap(1 bpp --> 8 bpp, arbitrary reduction) *
689  *------------------------------------------------------------------*/
721 PIX *
723  l_float32 scalefactor)
724 {
725 l_int32 w, h, minsrc, mindest;
726 l_float32 red;
727 PIX *pixs1, *pixs2, *pixt, *pixd;
728 
729  PROCNAME("pixScaleToGrayMipmap");
730 
731  if (!pixs)
732  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
733  if (pixGetDepth(pixs) != 1)
734  return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
735  if (scalefactor <= 0.0)
736  return (PIX *)ERROR_PTR("scalefactor <= 0.0", procName, NULL);
737  if (scalefactor >= 1.0)
738  return (PIX *)ERROR_PTR("scalefactor >= 1.0", procName, NULL);
739  pixGetDimensions(pixs, &w, &h, NULL);
740  minsrc = L_MIN(w, h);
741  mindest = (l_int32)((l_float32)minsrc * scalefactor);
742  if (mindest < 2)
743  return (PIX *)ERROR_PTR("scalefactor too small", procName, NULL);
744 
745  if (scalefactor > 0.5) {
746  pixs1 = pixConvert1To8(NULL, pixs, 255, 0);
747  pixs2 = pixScaleToGray2(pixs);
748  red = scalefactor;
749  } else if (scalefactor == 0.5) {
750  return pixScaleToGray2(pixs);
751  } else if (scalefactor > 0.25) {
752  pixs1 = pixScaleToGray2(pixs);
753  pixs2 = pixScaleToGray4(pixs);
754  red = 2. * scalefactor;
755  } else if (scalefactor == 0.25) {
756  return pixScaleToGray4(pixs);
757  } else if (scalefactor > 0.125) {
758  pixs1 = pixScaleToGray4(pixs);
759  pixs2 = pixScaleToGray8(pixs);
760  red = 4. * scalefactor;
761  } else if (scalefactor == 0.125) {
762  return pixScaleToGray8(pixs);
763  } else if (scalefactor > 0.0625) {
764  pixs1 = pixScaleToGray8(pixs);
765  pixs2 = pixScaleToGray16(pixs);
766  red = 8. * scalefactor;
767  } else if (scalefactor == 0.0625) {
768  return pixScaleToGray16(pixs);
769  } else { /* end of the pyramid; just do it */
770  red = 16.0 * scalefactor; /* will be <= 1.0 */
771  if ((pixt = pixScaleToGray16(pixs)) == NULL)
772  return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
773  if (red < 0.7)
774  pixd = pixScaleSmooth(pixt, red, red);
775  else
776  pixd = pixScaleGrayLI(pixt, red, red);
777  pixDestroy(&pixt);
778  return pixd;
779  }
780 
781  pixd = pixScaleMipmap(pixs1, pixs2, red);
782  pixCopyInputFormat(pixd, pixs);
783 
784  pixDestroy(&pixs1);
785  pixDestroy(&pixs2);
786  return pixd;
787 }
788 
789 
790 /*------------------------------------------------------------------*
791  * Grayscale scaling using mipmap *
792  *------------------------------------------------------------------*/
809 PIX *
811  PIX *pixs2,
812  l_float32 scale)
813 {
814 l_int32 ws1, hs1, ws2, hs2, wd, hd, wpls1, wpls2, wpld;
815 l_uint32 *datas1, *datas2, *datad;
816 PIX *pixd;
817 
818  PROCNAME("pixScaleMipmap");
819 
820  if (!pixs1 || pixGetDepth(pixs1) != 8 || pixGetColormap(pixs1))
821  return (PIX *)ERROR_PTR("pixs1 underdefined, not 8 bpp, or cmapped",
822  procName, NULL);
823  if (!pixs2 || pixGetDepth(pixs2) != 8 || pixGetColormap(pixs2))
824  return (PIX *)ERROR_PTR("pixs2 underdefined, not 8 bpp, or cmapped",
825  procName, NULL);
826  pixGetDimensions(pixs1, &ws1, &hs1, NULL);
827  pixGetDimensions(pixs2, &ws2, &hs2, NULL);
828  if (scale > 1.0 || scale < 0.5)
829  return (PIX *)ERROR_PTR("scale not in [0.5, 1.0]", procName, NULL);
830  if (ws1 < 2 * ws2)
831  return (PIX *)ERROR_PTR("invalid width ratio", procName, NULL);
832  if (hs1 < 2 * hs2)
833  return (PIX *)ERROR_PTR("invalid height ratio", procName, NULL);
834 
835  /* Generate wd and hd from the lower resolution dimensions,
836  * to guarantee staying within both src images */
837  datas1 = pixGetData(pixs1);
838  wpls1 = pixGetWpl(pixs1);
839  datas2 = pixGetData(pixs2);
840  wpls2 = pixGetWpl(pixs2);
841  wd = (l_int32)(2. * scale * pixGetWidth(pixs2));
842  hd = (l_int32)(2. * scale * pixGetHeight(pixs2));
843  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
844  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
845  pixCopyInputFormat(pixd, pixs1);
846  pixCopyResolution(pixd, pixs1);
847  pixScaleResolution(pixd, scale, scale);
848  datad = pixGetData(pixd);
849  wpld = pixGetWpl(pixd);
850 
851  scaleMipmapLow(datad, wd, hd, wpld, datas1, wpls1, datas2, wpls2, scale);
852  return pixd;
853 }
854 
855 
856 /*------------------------------------------------------------------*
857  * Replicated (integer) expansion *
858  *------------------------------------------------------------------*/
866 PIX *
868  l_int32 factor)
869 {
870 l_int32 w, h, d, wd, hd, wpls, wpld, start, i, j, k;
871 l_uint8 sval;
872 l_uint16 sval16;
873 l_uint32 sval32;
874 l_uint32 *lines, *datas, *lined, *datad;
875 PIX *pixd;
876 
877  PROCNAME("pixExpandReplicate");
878 
879  if (!pixs)
880  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
881  pixGetDimensions(pixs, &w, &h, &d);
882  if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
883  return (PIX *)ERROR_PTR("depth not in {1,2,4,8,16,32}", procName, NULL);
884  if (factor <= 0)
885  return (PIX *)ERROR_PTR("factor <= 0; invalid", procName, NULL);
886  if (factor == 1)
887  return pixCopy(NULL, pixs);
888 
889  if (d == 1)
890  return pixExpandBinaryReplicate(pixs, factor, factor);
891 
892  wd = factor * w;
893  hd = factor * h;
894  if ((pixd = pixCreate(wd, hd, d)) == NULL)
895  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
896  pixCopyColormap(pixd, pixs);
897  pixCopyInputFormat(pixd, pixs);
898  pixCopyResolution(pixd, pixs);
899  pixScaleResolution(pixd, (l_float32)factor, (l_float32)factor);
900  datas = pixGetData(pixs);
901  wpls = pixGetWpl(pixs);
902  datad = pixGetData(pixd);
903  wpld = pixGetWpl(pixd);
904 
905  switch (d) {
906  case 2:
907  for (i = 0; i < h; i++) {
908  lines = datas + i * wpls;
909  lined = datad + factor * i * wpld;
910  for (j = 0; j < w; j++) {
911  sval = GET_DATA_DIBIT(lines, j);
912  start = factor * j;
913  for (k = 0; k < factor; k++)
914  SET_DATA_DIBIT(lined, start + k, sval);
915  }
916  for (k = 1; k < factor; k++)
917  memcpy(lined + k * wpld, lined, 4 * wpld);
918  }
919  break;
920  case 4:
921  for (i = 0; i < h; i++) {
922  lines = datas + i * wpls;
923  lined = datad + factor * i * wpld;
924  for (j = 0; j < w; j++) {
925  sval = GET_DATA_QBIT(lines, j);
926  start = factor * j;
927  for (k = 0; k < factor; k++)
928  SET_DATA_QBIT(lined, start + k, sval);
929  }
930  for (k = 1; k < factor; k++)
931  memcpy(lined + k * wpld, lined, 4 * wpld);
932  }
933  break;
934  case 8:
935  for (i = 0; i < h; i++) {
936  lines = datas + i * wpls;
937  lined = datad + factor * i * wpld;
938  for (j = 0; j < w; j++) {
939  sval = GET_DATA_BYTE(lines, j);
940  start = factor * j;
941  for (k = 0; k < factor; k++)
942  SET_DATA_BYTE(lined, start + k, sval);
943  }
944  for (k = 1; k < factor; k++)
945  memcpy(lined + k * wpld, lined, 4 * wpld);
946  }
947  break;
948  case 16:
949  for (i = 0; i < h; i++) {
950  lines = datas + i * wpls;
951  lined = datad + factor * i * wpld;
952  for (j = 0; j < w; j++) {
953  sval16 = GET_DATA_TWO_BYTES(lines, j);
954  start = factor * j;
955  for (k = 0; k < factor; k++)
956  SET_DATA_TWO_BYTES(lined, start + k, sval16);
957  }
958  for (k = 1; k < factor; k++)
959  memcpy(lined + k * wpld, lined, 4 * wpld);
960  }
961  break;
962  case 32:
963  for (i = 0; i < h; i++) {
964  lines = datas + i * wpls;
965  lined = datad + factor * i * wpld;
966  for (j = 0; j < w; j++) {
967  sval32 = *(lines + j);
968  start = factor * j;
969  for (k = 0; k < factor; k++)
970  *(lined + start + k) = sval32;
971  }
972  for (k = 1; k < factor; k++)
973  memcpy(lined + k * wpld, lined, 4 * wpld);
974  }
975  break;
976  default:
977  fprintf(stderr, "invalid depth\n");
978  }
979 
980  if (d == 32 && pixGetSpp(pixs) == 4)
981  pixScaleAndTransferAlpha(pixd, pixs, (l_float32)factor,
982  (l_float32)factor);
983  return pixd;
984 }
985 
986 
987 /*-----------------------------------------------------------------------*
988  * Downscaling using min or max *
989  *-----------------------------------------------------------------------*/
1013 PIX *
1015  l_int32 xfact,
1016  l_int32 yfact,
1017  l_int32 type)
1018 {
1019 l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k, m;
1020 l_int32 minval, maxval, val;
1021 l_uint32 *datas, *datad, *lines, *lined;
1022 PIX *pixd;
1023 
1024  PROCNAME("pixScaleGrayMinMax");
1025 
1026  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1027  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1028  procName, NULL);
1029  pixGetDimensions(pixs, &ws, &hs, NULL);
1030  if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX &&
1031  type != L_CHOOSE_MAXDIFF)
1032  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1033  if (xfact < 1 || yfact < 1)
1034  return (PIX *)ERROR_PTR("xfact and yfact must be >= 1", procName, NULL);
1035 
1036  if (xfact == 2 && yfact == 2)
1037  return pixScaleGrayMinMax2(pixs, type);
1038 
1039  wd = ws / xfact;
1040  if (wd == 0) { /* single tile */
1041  wd = 1;
1042  xfact = ws;
1043  }
1044  hd = hs / yfact;
1045  if (hd == 0) { /* single tile */
1046  hd = 1;
1047  yfact = hs;
1048  }
1049  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1050  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1051  pixCopyInputFormat(pixd, pixs);
1052  datas = pixGetData(pixs);
1053  datad = pixGetData(pixd);
1054  wpls = pixGetWpl(pixs);
1055  wpld = pixGetWpl(pixd);
1056  for (i = 0; i < hd; i++) {
1057  lined = datad + i * wpld;
1058  for (j = 0; j < wd; j++) {
1059  if (type == L_CHOOSE_MIN || type == L_CHOOSE_MAXDIFF) {
1060  minval = 255;
1061  for (k = 0; k < yfact; k++) {
1062  lines = datas + (yfact * i + k) * wpls;
1063  for (m = 0; m < xfact; m++) {
1064  val = GET_DATA_BYTE(lines, xfact * j + m);
1065  if (val < minval)
1066  minval = val;
1067  }
1068  }
1069  }
1070  if (type == L_CHOOSE_MAX || type == L_CHOOSE_MAXDIFF) {
1071  maxval = 0;
1072  for (k = 0; k < yfact; k++) {
1073  lines = datas + (yfact * i + k) * wpls;
1074  for (m = 0; m < xfact; m++) {
1075  val = GET_DATA_BYTE(lines, xfact * j + m);
1076  if (val > maxval)
1077  maxval = val;
1078  }
1079  }
1080  }
1081  if (type == L_CHOOSE_MIN)
1082  SET_DATA_BYTE(lined, j, minval);
1083  else if (type == L_CHOOSE_MAX)
1084  SET_DATA_BYTE(lined, j, maxval);
1085  else /* type == L_CHOOSE_MAXDIFF */
1086  SET_DATA_BYTE(lined, j, maxval - minval);
1087  }
1088  }
1089 
1090  return pixd;
1091 }
1092 
1093 
1120 PIX *
1122  l_int32 type)
1123 {
1124 l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k;
1125 l_int32 minval, maxval;
1126 l_int32 val[4];
1127 l_uint32 *datas, *datad, *lines, *lined;
1128 PIX *pixd;
1129 
1130  PROCNAME("pixScaleGrayMinMax2");
1131 
1132  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1133  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1134  procName, NULL);
1135  pixGetDimensions(pixs, &ws, &hs, NULL);
1136  if (ws < 2 || hs < 2)
1137  return (PIX *)ERROR_PTR("too small: ws < 2 or hs < 2", procName, NULL);
1138  if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX &&
1139  type != L_CHOOSE_MAXDIFF)
1140  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1141 
1142  wd = ws / 2;
1143  hd = hs / 2;
1144  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1145  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1146  pixCopyInputFormat(pixd, pixs);
1147  datas = pixGetData(pixs);
1148  datad = pixGetData(pixd);
1149  wpls = pixGetWpl(pixs);
1150  wpld = pixGetWpl(pixd);
1151  for (i = 0; i < hd; i++) {
1152  lines = datas + 2 * i * wpls;
1153  lined = datad + i * wpld;
1154  for (j = 0; j < wd; j++) {
1155  val[0] = GET_DATA_BYTE(lines, 2 * j);
1156  val[1] = GET_DATA_BYTE(lines, 2 * j + 1);
1157  val[2] = GET_DATA_BYTE(lines + wpls, 2 * j);
1158  val[3] = GET_DATA_BYTE(lines + wpls, 2 * j + 1);
1159  if (type == L_CHOOSE_MIN || type == L_CHOOSE_MAXDIFF) {
1160  minval = 255;
1161  for (k = 0; k < 4; k++) {
1162  if (val[k] < minval)
1163  minval = val[k];
1164  }
1165  }
1166  if (type == L_CHOOSE_MAX || type == L_CHOOSE_MAXDIFF) {
1167  maxval = 0;
1168  for (k = 0; k < 4; k++) {
1169  if (val[k] > maxval)
1170  maxval = val[k];
1171  }
1172  }
1173  if (type == L_CHOOSE_MIN)
1174  SET_DATA_BYTE(lined, j, minval);
1175  else if (type == L_CHOOSE_MAX)
1176  SET_DATA_BYTE(lined, j, maxval);
1177  else /* type == L_CHOOSE_MAXDIFF */
1178  SET_DATA_BYTE(lined, j, maxval - minval);
1179  }
1180  }
1181 
1182  return pixd;
1183 }
1184 
1185 
1186 /*-----------------------------------------------------------------------*
1187  * Grayscale downscaling using rank value *
1188  *-----------------------------------------------------------------------*/
1202 PIX *
1204  l_int32 level1,
1205  l_int32 level2,
1206  l_int32 level3,
1207  l_int32 level4)
1208 {
1209 PIX *pixt1, *pixt2, *pixt3, *pixt4;
1210 
1211  PROCNAME("pixScaleGrayRankCascade");
1212 
1213  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1214  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1215  procName, NULL);
1216  if (level1 > 4 || level2 > 4 || level3 > 4 || level4 > 4)
1217  return (PIX *)ERROR_PTR("levels must not exceed 4", procName, NULL);
1218 
1219  if (level1 <= 0) {
1220  L_WARNING("no reduction because level1 not > 0\n", procName);
1221  return pixCopy(NULL, pixs);
1222  }
1223 
1224  pixt1 = pixScaleGrayRank2(pixs, level1);
1225  if (level2 <= 0)
1226  return pixt1;
1227 
1228  pixt2 = pixScaleGrayRank2(pixt1, level2);
1229  pixDestroy(&pixt1);
1230  if (level3 <= 0)
1231  return pixt2;
1232 
1233  pixt3 = pixScaleGrayRank2(pixt2, level3);
1234  pixDestroy(&pixt2);
1235  if (level4 <= 0)
1236  return pixt3;
1237 
1238  pixt4 = pixScaleGrayRank2(pixt3, level4);
1239  pixDestroy(&pixt3);
1240  return pixt4;
1241 }
1242 
1243 
1266 PIX *
1268  l_int32 rank)
1269 {
1270 l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k, m;
1271 l_int32 minval, maxval, rankval, minindex, maxindex;
1272 l_int32 val[4];
1273 l_int32 midval[4]; /* should only use 2 of these */
1274 l_uint32 *datas, *datad, *lines, *lined;
1275 PIX *pixd;
1276 
1277  PROCNAME("pixScaleGrayRank2");
1278 
1279  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1280  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1281  procName, NULL);
1282  if (rank < 1 || rank > 4)
1283  return (PIX *)ERROR_PTR("invalid rank", procName, NULL);
1284 
1285  if (rank == 1)
1286  return pixScaleGrayMinMax2(pixs, L_CHOOSE_MIN);
1287  if (rank == 4)
1288  return pixScaleGrayMinMax2(pixs, L_CHOOSE_MAX);
1289 
1290  pixGetDimensions(pixs, &ws, &hs, NULL);
1291  wd = ws / 2;
1292  hd = hs / 2;
1293  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1294  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1295  pixCopyInputFormat(pixd, pixs);
1296  datas = pixGetData(pixs);
1297  datad = pixGetData(pixd);
1298  wpls = pixGetWpl(pixs);
1299  wpld = pixGetWpl(pixd);
1300  for (i = 0; i < hd; i++) {
1301  lines = datas + 2 * i * wpls;
1302  lined = datad + i * wpld;
1303  for (j = 0; j < wd; j++) {
1304  val[0] = GET_DATA_BYTE(lines, 2 * j);
1305  val[1] = GET_DATA_BYTE(lines, 2 * j + 1);
1306  val[2] = GET_DATA_BYTE(lines + wpls, 2 * j);
1307  val[3] = GET_DATA_BYTE(lines + wpls, 2 * j + 1);
1308  minval = maxval = val[0];
1309  minindex = maxindex = 0;
1310  for (k = 1; k < 4; k++) {
1311  if (val[k] < minval) {
1312  minval = val[k];
1313  minindex = k;
1314  continue;
1315  }
1316  if (val[k] > maxval) {
1317  maxval = val[k];
1318  maxindex = k;
1319  }
1320  }
1321  for (k = 0, m = 0; k < 4; k++) {
1322  if (k == minindex || k == maxindex)
1323  continue;
1324  midval[m++] = val[k];
1325  }
1326  if (m > 2) /* minval == maxval; all val[k] are the same */
1327  rankval = minval;
1328  else if (rank == 2)
1329  rankval = L_MIN(midval[0], midval[1]);
1330  else /* rank == 3 */
1331  rankval = L_MAX(midval[0], midval[1]);
1332  SET_DATA_BYTE(lined, j, rankval);
1333  }
1334  }
1335 
1336  return pixd;
1337 }
1338 
1339 
1340 /*------------------------------------------------------------------------*
1341  * Helper function for transferring alpha with scaling *
1342  *------------------------------------------------------------------------*/
1356 l_int32
1358  PIX *pixs,
1359  l_float32 scalex,
1360  l_float32 scaley)
1361 {
1362 PIX *pix1, *pix2;
1363 
1364  PROCNAME("pixScaleAndTransferAlpha");
1365 
1366  if (!pixs || !pixd)
1367  return ERROR_INT("pixs and pixd not both defined", procName, 1);
1368  if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
1369  return ERROR_INT("pixs not 32 bpp and 4 spp", procName, 1);
1370  if (pixGetDepth(pixd) != 32)
1371  return ERROR_INT("pixd not 32 bpp", procName, 1);
1372 
1373  if (scalex == 1.0 && scaley == 1.0) {
1374  pixCopyRGBComponent(pixd, pixs, L_ALPHA_CHANNEL);
1375  return 0;
1376  }
1377 
1378  pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
1379  pix2 = pixScale(pix1, scalex, scaley);
1380  pixSetRGBComponent(pixd, pix2, L_ALPHA_CHANNEL);
1381  pixDestroy(&pix1);
1382  pixDestroy(&pix2);
1383  return 0;
1384 }
1385 
1386 
1387 /*------------------------------------------------------------------------*
1388  * RGB scaling including alpha (blend) component and gamma transform *
1389  *------------------------------------------------------------------------*/
1434 PIX *
1436  l_float32 scalex,
1437  l_float32 scaley,
1438  PIX *pixg,
1439  l_float32 fract)
1440 {
1441 l_int32 ws, hs, d, spp;
1442 PIX *pixd, *pix32, *pixg2, *pixgs;
1443 
1444  PROCNAME("pixScaleWithAlpha");
1445 
1446  if (!pixs)
1447  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1448  pixGetDimensions(pixs, &ws, &hs, &d);
1449  if (d != 32 && !pixGetColormap(pixs))
1450  return (PIX *)ERROR_PTR("pixs not cmapped or 32 bpp", procName, NULL);
1451  if (scalex <= 0.0 || scaley <= 0.0)
1452  return (PIX *)ERROR_PTR("scale factor <= 0.0", procName, NULL);
1453  if (pixg && pixGetDepth(pixg) != 8) {
1454  L_WARNING("pixg not 8 bpp; using 'fract' transparent alpha\n",
1455  procName);
1456  pixg = NULL;
1457  }
1458  if (!pixg && (fract < 0.0 || fract > 1.0)) {
1459  L_WARNING("invalid fract; using fully opaque\n", procName);
1460  fract = 1.0;
1461  }
1462  if (!pixg && fract == 0.0)
1463  L_WARNING("transparent alpha; image will not be blended\n", procName);
1464 
1465  /* Make sure input to scaling is 32 bpp rgb, and scale it */
1466  if (d != 32)
1467  pix32 = pixConvertTo32(pixs);
1468  else
1469  pix32 = pixClone(pixs);
1470  spp = pixGetSpp(pix32);
1471  pixSetSpp(pix32, 3); /* ignore the alpha channel for scaling */
1472  pixd = pixScale(pix32, scalex, scaley);
1473  pixSetSpp(pix32, spp); /* restore initial value in case it's a clone */
1474  pixDestroy(&pix32);
1475 
1476  /* Set up alpha layer with a fading border and scale it */
1477  if (!pixg) {
1478  pixg2 = pixCreate(ws, hs, 8);
1479  if (fract == 1.0)
1480  pixSetAll(pixg2);
1481  else if (fract > 0.0)
1482  pixSetAllArbitrary(pixg2, (l_int32)(255.0 * fract));
1483  } else {
1484  pixg2 = pixResizeToMatch(pixg, NULL, ws, hs);
1485  }
1486  if (ws > 10 && hs > 10) { /* see note 4 */
1487  pixSetBorderRingVal(pixg2, 1,
1488  (l_int32)(255.0 * fract * AlphaMaskBorderVals[0]));
1489  pixSetBorderRingVal(pixg2, 2,
1490  (l_int32)(255.0 * fract * AlphaMaskBorderVals[1]));
1491  }
1492  pixgs = pixScaleGeneral(pixg2, scalex, scaley, 0.0, 0);
1493 
1494  /* Combine into a 4 spp result */
1495  pixSetRGBComponent(pixd, pixgs, L_ALPHA_CHANNEL);
1496  pixCopyInputFormat(pixd, pixs);
1497 
1498  pixDestroy(&pixg2);
1499  pixDestroy(&pixgs);
1500  return pixd;
1501 }
1502 
1503 
1504 /* ================================================================ *
1505  * Low level static functions *
1506  * ================================================================ */
1507 
1508 /*------------------------------------------------------------------*
1509  * Scale-to-gray 2x *
1510  *------------------------------------------------------------------*/
1533 static void
1534 scaleToGray2Low(l_uint32 *datad,
1535  l_int32 wd,
1536  l_int32 hd,
1537  l_int32 wpld,
1538  l_uint32 *datas,
1539  l_int32 wpls,
1540  l_uint32 *sumtab,
1541  l_uint8 *valtab)
1542 {
1543 l_int32 i, j, l, k, m, wd4, extra;
1544 l_uint32 sbyte1, sbyte2, sum;
1545 l_uint32 *lines, *lined;
1546 
1547  /* i indexes the dest lines
1548  * l indexes the source lines
1549  * j indexes the dest bytes
1550  * k indexes the source bytes
1551  * We take two bytes from the source (in 2 lines of 8 pixels
1552  * each) and convert them into four 8 bpp bytes of the dest. */
1553  wd4 = wd & 0xfffffffc;
1554  extra = wd - wd4;
1555  for (i = 0, l = 0; i < hd; i++, l += 2) {
1556  lines = datas + l * wpls;
1557  lined = datad + i * wpld;
1558  for (j = 0, k = 0; j < wd4; j += 4, k++) {
1559  sbyte1 = GET_DATA_BYTE(lines, k);
1560  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1561  sum = sumtab[sbyte1] + sumtab[sbyte2];
1562  SET_DATA_BYTE(lined, j, valtab[sum >> 24]);
1563  SET_DATA_BYTE(lined, j + 1, valtab[(sum >> 16) & 0xff]);
1564  SET_DATA_BYTE(lined, j + 2, valtab[(sum >> 8) & 0xff]);
1565  SET_DATA_BYTE(lined, j + 3, valtab[sum & 0xff]);
1566  }
1567  if (extra > 0) {
1568  sbyte1 = GET_DATA_BYTE(lines, k);
1569  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1570  sum = sumtab[sbyte1] + sumtab[sbyte2];
1571  for (m = 0; m < extra; m++) {
1572  SET_DATA_BYTE(lined, j + m,
1573  valtab[((sum >> (24 - 8 * m)) & 0xff)]);
1574  }
1575  }
1576 
1577  }
1578 
1579  return;
1580 }
1581 
1582 
1592 static l_uint32 *
1594 {
1595 l_int32 i;
1596 l_int32 sum[] = {0, 1, 1, 2};
1597 l_uint32 *tab;
1598 
1599  PROCNAME("makeSumTabSG2");
1600 
1601  if ((tab = (l_uint32 *)LEPT_CALLOC(256, sizeof(l_uint32))) == NULL)
1602  return (l_uint32 *)ERROR_PTR("tab not made", procName, NULL);
1603 
1604  /* Pack the four sums separately in four bytes */
1605  for (i = 0; i < 256; i++) {
1606  tab[i] = (sum[i & 0x3] | sum[(i >> 2) & 0x3] << 8 |
1607  sum[(i >> 4) & 0x3] << 16 | sum[(i >> 6) & 0x3] << 24);
1608  }
1609  return tab;
1610 }
1611 
1612 
1623 static l_uint8 *
1625 {
1626 l_int32 i;
1627 l_uint8 *tab;
1628 
1629  PROCNAME("makeValTabSG2");
1630 
1631  if ((tab = (l_uint8 *)LEPT_CALLOC(5, sizeof(l_uint8))) == NULL)
1632  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
1633  for (i = 0; i < 5; i++)
1634  tab[i] = 255 - (i * 255) / 4;
1635  return tab;
1636 }
1637 
1638 
1639 /*------------------------------------------------------------------*
1640  * Scale-to-gray 3x *
1641  *------------------------------------------------------------------*/
1677 static void
1678 scaleToGray3Low(l_uint32 *datad,
1679  l_int32 wd,
1680  l_int32 hd,
1681  l_int32 wpld,
1682  l_uint32 *datas,
1683  l_int32 wpls,
1684  l_uint32 *sumtab,
1685  l_uint8 *valtab)
1686 {
1687 l_int32 i, j, l, k;
1688 l_uint32 threebytes1, threebytes2, threebytes3, sum;
1689 l_uint32 *lines, *lined;
1690 
1691  /* i indexes the dest lines
1692  * l indexes the source lines
1693  * j indexes the dest bytes
1694  * k indexes the source bytes
1695  * We take 9 bytes from the source (72 binary pixels
1696  * in three lines of 24 pixels each) and convert it
1697  * into 8 bytes of the dest (8 8bpp pixels in one line) */
1698  for (i = 0, l = 0; i < hd; i++, l += 3) {
1699  lines = datas + l * wpls;
1700  lined = datad + i * wpld;
1701  for (j = 0, k = 0; j < wd; j += 8, k += 3) {
1702  threebytes1 = (GET_DATA_BYTE(lines, k) << 16) |
1703  (GET_DATA_BYTE(lines, k + 1) << 8) |
1704  GET_DATA_BYTE(lines, k + 2);
1705  threebytes2 = (GET_DATA_BYTE(lines + wpls, k) << 16) |
1706  (GET_DATA_BYTE(lines + wpls, k + 1) << 8) |
1707  GET_DATA_BYTE(lines + wpls, k + 2);
1708  threebytes3 = (GET_DATA_BYTE(lines + 2 * wpls, k) << 16) |
1709  (GET_DATA_BYTE(lines + 2 * wpls, k + 1) << 8) |
1710  GET_DATA_BYTE(lines + 2 * wpls, k + 2);
1711 
1712  sum = sumtab[(threebytes1 >> 18)] +
1713  sumtab[(threebytes2 >> 18)] +
1714  sumtab[(threebytes3 >> 18)];
1715  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 2)]);
1716  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1717 
1718  sum = sumtab[((threebytes1 >> 12) & 0x3f)] +
1719  sumtab[((threebytes2 >> 12) & 0x3f)] +
1720  sumtab[((threebytes3 >> 12) & 0x3f)];
1721  SET_DATA_BYTE(lined, j + 2, valtab[GET_DATA_BYTE(&sum, 2)]);
1722  SET_DATA_BYTE(lined, j + 3, valtab[GET_DATA_BYTE(&sum, 3)]);
1723 
1724  sum = sumtab[((threebytes1 >> 6) & 0x3f)] +
1725  sumtab[((threebytes2 >> 6) & 0x3f)] +
1726  sumtab[((threebytes3 >> 6) & 0x3f)];
1727  SET_DATA_BYTE(lined, j + 4, valtab[GET_DATA_BYTE(&sum, 2)]);
1728  SET_DATA_BYTE(lined, j + 5, valtab[GET_DATA_BYTE(&sum, 3)]);
1729 
1730  sum = sumtab[(threebytes1 & 0x3f)] +
1731  sumtab[(threebytes2 & 0x3f)] +
1732  sumtab[(threebytes3 & 0x3f)];
1733  SET_DATA_BYTE(lined, j + 6, valtab[GET_DATA_BYTE(&sum, 2)]);
1734  SET_DATA_BYTE(lined, j + 7, valtab[GET_DATA_BYTE(&sum, 3)]);
1735  }
1736  }
1737 
1738  return;
1739 }
1740 
1741 
1742 
1753 static l_uint32 *
1755 {
1756 l_int32 i;
1757 l_int32 sum[] = {0, 1, 1, 2, 1, 2, 2, 3};
1758 l_uint32 *tab;
1759 
1760  PROCNAME("makeSumTabSG3");
1761 
1762  if ((tab = (l_uint32 *)LEPT_CALLOC(64, sizeof(l_uint32))) == NULL)
1763  return (l_uint32 *)ERROR_PTR("tab not made", procName, NULL);
1764 
1765  /* Pack the two sums separately in two bytes */
1766  for (i = 0; i < 64; i++) {
1767  tab[i] = (sum[i & 0x07]) | (sum[(i >> 3) & 0x07] << 8);
1768  }
1769  return tab;
1770 }
1771 
1772 
1781 static l_uint8 *
1783 {
1784 l_int32 i;
1785 l_uint8 *tab;
1786 
1787  PROCNAME("makeValTabSG3");
1788 
1789  if ((tab = (l_uint8 *)LEPT_CALLOC(10, sizeof(l_uint8))) == NULL)
1790  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
1791  for (i = 0; i < 10; i++)
1792  tab[i] = 0xff - (i * 255) / 9;
1793  return tab;
1794 }
1795 
1796 
1797 /*------------------------------------------------------------------*
1798  * Scale-to-gray 4x *
1799  *------------------------------------------------------------------*/
1822 static void
1823 scaleToGray4Low(l_uint32 *datad,
1824  l_int32 wd,
1825  l_int32 hd,
1826  l_int32 wpld,
1827  l_uint32 *datas,
1828  l_int32 wpls,
1829  l_uint32 *sumtab,
1830  l_uint8 *valtab)
1831 {
1832 l_int32 i, j, l, k;
1833 l_uint32 sbyte1, sbyte2, sbyte3, sbyte4, sum;
1834 l_uint32 *lines, *lined;
1835 
1836  /* i indexes the dest lines
1837  * l indexes the source lines
1838  * j indexes the dest bytes
1839  * k indexes the source bytes
1840  * We take four bytes from the source (in 4 lines of 8 pixels
1841  * each) and convert it into two 8 bpp bytes of the dest. */
1842  for (i = 0, l = 0; i < hd; i++, l += 4) {
1843  lines = datas + l * wpls;
1844  lined = datad + i * wpld;
1845  for (j = 0, k = 0; j < wd; j += 2, k++) {
1846  sbyte1 = GET_DATA_BYTE(lines, k);
1847  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1848  sbyte3 = GET_DATA_BYTE(lines + 2 * wpls, k);
1849  sbyte4 = GET_DATA_BYTE(lines + 3 * wpls, k);
1850  sum = sumtab[sbyte1] + sumtab[sbyte2] +
1851  sumtab[sbyte3] + sumtab[sbyte4];
1852  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 2)]);
1853  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1854  }
1855  }
1856 
1857  return;
1858 }
1859 
1860 
1870 static l_uint32 *
1872 {
1873 l_int32 i;
1874 l_int32 sum[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1875 l_uint32 *tab;
1876 
1877  PROCNAME("makeSumTabSG4");
1878 
1879  if ((tab = (l_uint32 *)LEPT_CALLOC(256, sizeof(l_uint32))) == NULL)
1880  return (l_uint32 *)ERROR_PTR("tab not made", procName, NULL);
1881 
1882  /* Pack the two sums separately in two bytes */
1883  for (i = 0; i < 256; i++) {
1884  tab[i] = (sum[i & 0xf]) | (sum[(i >> 4) & 0xf] << 8);
1885  }
1886  return tab;
1887 }
1888 
1889 
1900 static l_uint8 *
1902 {
1903 l_int32 i;
1904 l_uint8 *tab;
1905 
1906  PROCNAME("makeValTabSG4");
1907 
1908  if ((tab = (l_uint8 *)LEPT_CALLOC(17, sizeof(l_uint8))) == NULL)
1909  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
1910  for (i = 0; i < 17; i++)
1911  tab[i] = 0xff - (i * 255) / 16;
1912  return tab;
1913 }
1914 
1915 
1916 /*------------------------------------------------------------------*
1917  * Scale-to-gray 6x *
1918  *------------------------------------------------------------------*/
1954 static void
1955 scaleToGray6Low(l_uint32 *datad,
1956  l_int32 wd,
1957  l_int32 hd,
1958  l_int32 wpld,
1959  l_uint32 *datas,
1960  l_int32 wpls,
1961  l_int32 *tab8,
1962  l_uint8 *valtab)
1963 {
1964 l_int32 i, j, l, k;
1965 l_uint32 threebytes1, threebytes2, threebytes3;
1966 l_uint32 threebytes4, threebytes5, threebytes6, sum;
1967 l_uint32 *lines, *lined;
1968 
1969  /* i indexes the dest lines
1970  * l indexes the source lines
1971  * j indexes the dest bytes
1972  * k indexes the source bytes
1973  * We take 18 bytes from the source (144 binary pixels
1974  * in six lines of 24 pixels each) and convert it
1975  * into 4 bytes of the dest (four 8 bpp pixels in one line) */
1976  for (i = 0, l = 0; i < hd; i++, l += 6) {
1977  lines = datas + l * wpls;
1978  lined = datad + i * wpld;
1979  for (j = 0, k = 0; j < wd; j += 4, k += 3) {
1980  /* First grab the 18 bytes, 3 at a time, and put each set
1981  * of 3 bytes into the LS bytes of a 32-bit word. */
1982  threebytes1 = (GET_DATA_BYTE(lines, k) << 16) |
1983  (GET_DATA_BYTE(lines, k + 1) << 8) |
1984  GET_DATA_BYTE(lines, k + 2);
1985  threebytes2 = (GET_DATA_BYTE(lines + wpls, k) << 16) |
1986  (GET_DATA_BYTE(lines + wpls, k + 1) << 8) |
1987  GET_DATA_BYTE(lines + wpls, k + 2);
1988  threebytes3 = (GET_DATA_BYTE(lines + 2 * wpls, k) << 16) |
1989  (GET_DATA_BYTE(lines + 2 * wpls, k + 1) << 8) |
1990  GET_DATA_BYTE(lines + 2 * wpls, k + 2);
1991  threebytes4 = (GET_DATA_BYTE(lines + 3 * wpls, k) << 16) |
1992  (GET_DATA_BYTE(lines + 3 * wpls, k + 1) << 8) |
1993  GET_DATA_BYTE(lines + 3 * wpls, k + 2);
1994  threebytes5 = (GET_DATA_BYTE(lines + 4 * wpls, k) << 16) |
1995  (GET_DATA_BYTE(lines + 4 * wpls, k + 1) << 8) |
1996  GET_DATA_BYTE(lines + 4 * wpls, k + 2);
1997  threebytes6 = (GET_DATA_BYTE(lines + 5 * wpls, k) << 16) |
1998  (GET_DATA_BYTE(lines + 5 * wpls, k + 1) << 8) |
1999  GET_DATA_BYTE(lines + 5 * wpls, k + 2);
2000 
2001  /* Sum first set of 36 bits and convert to 0-255 */
2002  sum = tab8[(threebytes1 >> 18)] +
2003  tab8[(threebytes2 >> 18)] +
2004  tab8[(threebytes3 >> 18)] +
2005  tab8[(threebytes4 >> 18)] +
2006  tab8[(threebytes5 >> 18)] +
2007  tab8[(threebytes6 >> 18)];
2008  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 3)]);
2009 
2010  /* Ditto for second set */
2011  sum = tab8[((threebytes1 >> 12) & 0x3f)] +
2012  tab8[((threebytes2 >> 12) & 0x3f)] +
2013  tab8[((threebytes3 >> 12) & 0x3f)] +
2014  tab8[((threebytes4 >> 12) & 0x3f)] +
2015  tab8[((threebytes5 >> 12) & 0x3f)] +
2016  tab8[((threebytes6 >> 12) & 0x3f)];
2017  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
2018 
2019  sum = tab8[((threebytes1 >> 6) & 0x3f)] +
2020  tab8[((threebytes2 >> 6) & 0x3f)] +
2021  tab8[((threebytes3 >> 6) & 0x3f)] +
2022  tab8[((threebytes4 >> 6) & 0x3f)] +
2023  tab8[((threebytes5 >> 6) & 0x3f)] +
2024  tab8[((threebytes6 >> 6) & 0x3f)];
2025  SET_DATA_BYTE(lined, j + 2, valtab[GET_DATA_BYTE(&sum, 3)]);
2026 
2027  sum = tab8[(threebytes1 & 0x3f)] +
2028  tab8[(threebytes2 & 0x3f)] +
2029  tab8[(threebytes3 & 0x3f)] +
2030  tab8[(threebytes4 & 0x3f)] +
2031  tab8[(threebytes5 & 0x3f)] +
2032  tab8[(threebytes6 & 0x3f)];
2033  SET_DATA_BYTE(lined, j + 3, valtab[GET_DATA_BYTE(&sum, 3)]);
2034  }
2035  }
2036  return;
2037 }
2038 
2039 
2048 static l_uint8 *
2050 {
2051 l_int32 i;
2052 l_uint8 *tab;
2053 
2054  PROCNAME("makeValTabSG6");
2055 
2056  if ((tab = (l_uint8 *)LEPT_CALLOC(37, sizeof(l_uint8))) == NULL)
2057  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
2058  for (i = 0; i < 37; i++)
2059  tab[i] = 0xff - (i * 255) / 36;
2060  return tab;
2061 }
2062 
2063 
2064 /*------------------------------------------------------------------*
2065  * Scale-to-gray 8x *
2066  *------------------------------------------------------------------*/
2087 static void
2088 scaleToGray8Low(l_uint32 *datad,
2089  l_int32 wd,
2090  l_int32 hd,
2091  l_int32 wpld,
2092  l_uint32 *datas,
2093  l_int32 wpls,
2094  l_int32 *tab8,
2095  l_uint8 *valtab)
2096 {
2097 l_int32 i, j, k;
2098 l_int32 sbyte0, sbyte1, sbyte2, sbyte3, sbyte4, sbyte5, sbyte6, sbyte7, sum;
2099 l_uint32 *lines, *lined;
2100 
2101  /* i indexes the dest lines
2102  * k indexes the source lines
2103  * j indexes the src and dest bytes
2104  * We take 8 bytes from the source (in 8 lines of 8 pixels
2105  * each) and convert it into one 8 bpp byte of the dest. */
2106  for (i = 0, k = 0; i < hd; i++, k += 8) {
2107  lines = datas + k * wpls;
2108  lined = datad + i * wpld;
2109  for (j = 0; j < wd; j++) {
2110  sbyte0 = GET_DATA_BYTE(lines, j);
2111  sbyte1 = GET_DATA_BYTE(lines + wpls, j);
2112  sbyte2 = GET_DATA_BYTE(lines + 2 * wpls, j);
2113  sbyte3 = GET_DATA_BYTE(lines + 3 * wpls, j);
2114  sbyte4 = GET_DATA_BYTE(lines + 4 * wpls, j);
2115  sbyte5 = GET_DATA_BYTE(lines + 5 * wpls, j);
2116  sbyte6 = GET_DATA_BYTE(lines + 6 * wpls, j);
2117  sbyte7 = GET_DATA_BYTE(lines + 7 * wpls, j);
2118  sum = tab8[sbyte0] + tab8[sbyte1] +
2119  tab8[sbyte2] + tab8[sbyte3] +
2120  tab8[sbyte4] + tab8[sbyte5] +
2121  tab8[sbyte6] + tab8[sbyte7];
2122  SET_DATA_BYTE(lined, j, valtab[sum]);
2123  }
2124  }
2125 
2126  return;
2127 }
2128 
2129 
2138 static l_uint8 *
2140 {
2141 l_int32 i;
2142 l_uint8 *tab;
2143 
2144  PROCNAME("makeValTabSG8");
2145 
2146  if ((tab = (l_uint8 *)LEPT_CALLOC(65, sizeof(l_uint8))) == NULL)
2147  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
2148  for (i = 0; i < 65; i++)
2149  tab[i] = 0xff - (i * 255) / 64;
2150  return tab;
2151 }
2152 
2153 
2154 /*------------------------------------------------------------------*
2155  * Scale-to-gray 16x *
2156  *------------------------------------------------------------------*/
2176 static void
2177 scaleToGray16Low(l_uint32 *datad,
2178  l_int32 wd,
2179  l_int32 hd,
2180  l_int32 wpld,
2181  l_uint32 *datas,
2182  l_int32 wpls,
2183  l_int32 *tab8)
2184 {
2185 l_int32 i, j, k, m;
2186 l_int32 sum;
2187 l_uint32 *lines, *lined;
2188 
2189  /* i indexes the dest lines
2190  * k indexes the source lines
2191  * j indexes the dest bytes
2192  * m indexes the src bytes
2193  * We take 32 bytes from the source (in 16 lines of 16 pixels
2194  * each) and convert it into one 8 bpp byte of the dest. */
2195  for (i = 0, k = 0; i < hd; i++, k += 16) {
2196  lines = datas + k * wpls;
2197  lined = datad + i * wpld;
2198  for (j = 0; j < wd; j++) {
2199  m = 2 * j;
2200  sum = tab8[GET_DATA_BYTE(lines, m)];
2201  sum += tab8[GET_DATA_BYTE(lines, m + 1)];
2202  sum += tab8[GET_DATA_BYTE(lines + wpls, m)];
2203  sum += tab8[GET_DATA_BYTE(lines + wpls, m + 1)];
2204  sum += tab8[GET_DATA_BYTE(lines + 2 * wpls, m)];
2205  sum += tab8[GET_DATA_BYTE(lines + 2 * wpls, m + 1)];
2206  sum += tab8[GET_DATA_BYTE(lines + 3 * wpls, m)];
2207  sum += tab8[GET_DATA_BYTE(lines + 3 * wpls, m + 1)];
2208  sum += tab8[GET_DATA_BYTE(lines + 4 * wpls, m)];
2209  sum += tab8[GET_DATA_BYTE(lines + 4 * wpls, m + 1)];
2210  sum += tab8[GET_DATA_BYTE(lines + 5 * wpls, m)];
2211  sum += tab8[GET_DATA_BYTE(lines + 5 * wpls, m + 1)];
2212  sum += tab8[GET_DATA_BYTE(lines + 6 * wpls, m)];
2213  sum += tab8[GET_DATA_BYTE(lines + 6 * wpls, m + 1)];
2214  sum += tab8[GET_DATA_BYTE(lines + 7 * wpls, m)];
2215  sum += tab8[GET_DATA_BYTE(lines + 7 * wpls, m + 1)];
2216  sum += tab8[GET_DATA_BYTE(lines + 8 * wpls, m)];
2217  sum += tab8[GET_DATA_BYTE(lines + 8 * wpls, m + 1)];
2218  sum += tab8[GET_DATA_BYTE(lines + 9 * wpls, m)];
2219  sum += tab8[GET_DATA_BYTE(lines + 9 * wpls, m + 1)];
2220  sum += tab8[GET_DATA_BYTE(lines + 10 * wpls, m)];
2221  sum += tab8[GET_DATA_BYTE(lines + 10 * wpls, m + 1)];
2222  sum += tab8[GET_DATA_BYTE(lines + 11 * wpls, m)];
2223  sum += tab8[GET_DATA_BYTE(lines + 11 * wpls, m + 1)];
2224  sum += tab8[GET_DATA_BYTE(lines + 12 * wpls, m)];
2225  sum += tab8[GET_DATA_BYTE(lines + 12 * wpls, m + 1)];
2226  sum += tab8[GET_DATA_BYTE(lines + 13 * wpls, m)];
2227  sum += tab8[GET_DATA_BYTE(lines + 13 * wpls, m + 1)];
2228  sum += tab8[GET_DATA_BYTE(lines + 14 * wpls, m)];
2229  sum += tab8[GET_DATA_BYTE(lines + 14 * wpls, m + 1)];
2230  sum += tab8[GET_DATA_BYTE(lines + 15 * wpls, m)];
2231  sum += tab8[GET_DATA_BYTE(lines + 15 * wpls, m + 1)];
2232  sum = L_MIN(sum, 255);
2233  SET_DATA_BYTE(lined, j, 255 - sum);
2234  }
2235  }
2236 
2237  return;
2238 }
2239 
2240 
2241 
2242 /*------------------------------------------------------------------*
2243  * Grayscale mipmap *
2244  *------------------------------------------------------------------*/
2252 static l_int32
2253 scaleMipmapLow(l_uint32 *datad,
2254  l_int32 wd,
2255  l_int32 hd,
2256  l_int32 wpld,
2257  l_uint32 *datas1,
2258  l_int32 wpls1,
2259  l_uint32 *datas2,
2260  l_int32 wpls2,
2261  l_float32 red)
2262 {
2263 l_int32 i, j, val1, val2, val, row2, col2;
2264 l_int32 *srow, *scol;
2265 l_uint32 *lines1, *lines2, *lined;
2266 l_float32 ratio, w1, w2;
2267 
2268  PROCNAME("scaleMipmapLow");
2269 
2270  /* Clear dest */
2271  memset((char *)datad, 0, 4 * wpld * hd);
2272 
2273  /* Each dest pixel at (j,i) is computed by interpolating
2274  between the two src images at the corresponding location.
2275  We store the UL corner locations of the square of
2276  src pixels in thelower-resolution image that correspond
2277  to dest pixel (j,i). The are labeled by the arrays
2278  srow[i], scol[j]. The UL corner locations of the higher
2279  resolution src pixels are obtained from these arrays
2280  by multiplying by 2. */
2281  if ((srow = (l_int32 *)LEPT_CALLOC(hd, sizeof(l_int32))) == NULL)
2282  return ERROR_INT("srow not made", procName, 1);
2283  if ((scol = (l_int32 *)LEPT_CALLOC(wd, sizeof(l_int32))) == NULL) {
2284  LEPT_FREE(srow);
2285  return ERROR_INT("scol not made", procName, 1);
2286  }
2287  ratio = 1. / (2. * red); /* 0.5 for red = 1, 1 for red = 0.5 */
2288  for (i = 0; i < hd; i++)
2289  srow[i] = (l_int32)(ratio * i);
2290  for (j = 0; j < wd; j++)
2291  scol[j] = (l_int32)(ratio * j);
2292 
2293  /* Get weights for linear interpolation: these are the
2294  * 'distances' of the dest image plane from the two
2295  * src image planes. */
2296  w1 = 2. * red - 1.; /* w1 --> 1 as red --> 1 */
2297  w2 = 1. - w1;
2298 
2299  /* For each dest pixel, compute linear interpolation */
2300  for (i = 0; i < hd; i++) {
2301  row2 = srow[i];
2302  lines1 = datas1 + 2 * row2 * wpls1;
2303  lines2 = datas2 + row2 * wpls2;
2304  lined = datad + i * wpld;
2305  for (j = 0; j < wd; j++) {
2306  col2 = scol[j];
2307  val1 = GET_DATA_BYTE(lines1, 2 * col2);
2308  val2 = GET_DATA_BYTE(lines2, col2);
2309  val = (l_int32)(w1 * val1 + w2 * val2);
2310  SET_DATA_BYTE(lined, j, val);
2311  }
2312  }
2313 
2314  LEPT_FREE(srow);
2315  LEPT_FREE(scol);
2316  return 0;
2317 }
PIX * pixScaleWithAlpha(PIX *pixs, l_float32 scalex, l_float32 scaley, PIX *pixg, l_float32 fract)
pixScaleWithAlpha()
Definition: scale2.c:1435
static l_uint8 * makeValTabSG2(void)
makeValTabSG2()
Definition: scale2.c:1624
l_int32 pixCopyColormap(PIX *pixd, PIX *pixs)
pixCopyColormap()
Definition: pix1.c:735
PIX * pixScaleToGray(PIX *pixs, l_float32 scalefactor)
pixScaleToGray()
Definition: scale2.c:204
static l_uint32 * makeSumTabSG4(void)
makeSumTabSG4()
Definition: scale2.c:1871
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
PIX * pixScaleGrayRankCascade(PIX *pixs, l_int32 level1, l_int32 level2, l_int32 level3, l_int32 level4)
pixScaleGrayRankCascade()
Definition: scale2.c:1203
PIX * pixScaleGrayMinMax(PIX *pixs, l_int32 xfact, l_int32 yfact, l_int32 type)
pixScaleGrayMinMax()
Definition: scale2.c:1014
l_int32 pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition: pix2.c:2451
PIX * pixScaleGrayRank2(PIX *pixs, l_int32 rank)
pixScaleGrayRank2()
Definition: scale2.c:1267
l_int32 pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:864
static l_uint8 * makeValTabSG6(void)
makeValTabSG6()
Definition: scale2.c:2049
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
static l_uint32 * makeSumTabSG2(void)
makeSumTabSG2()
Definition: scale2.c:1593
PIX * pixScaleGeneral(PIX *pixs, l_float32 scalex, l_float32 scaley, l_float32 sharpfract, l_int32 sharpwidth)
pixScaleGeneral()
Definition: scale1.c:374
PIX * pixScaleToGray6(PIX *pixs)
pixScaleToGray6()
Definition: scale2.c:552
#define SET_DATA_QBIT(pdata, n, val)
Definition: arrayaccess.h:162
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1602
PIX * pixScaleToGray3(PIX *pixs)
pixScaleToGray3()
Definition: scale2.c:443
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition: pix2.c:2392
#define SET_DATA_DIBIT(pdata, n, val)
Definition: arrayaccess.h:143
PIX * pixScaleToGray8(PIX *pixs)
pixScaleToGray8()
Definition: scale2.c:600
PIX * pixScaleBinary(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBinary()
Definition: scale1.c:2105
static void scaleToGray16Low(l_uint32 *datad, l_int32 wd, l_int32 hd, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 *tab8)
scaleToGray16Low()
Definition: scale2.c:2177
static void scaleToGray3Low(l_uint32 *datad, l_int32 wd, l_int32 hd, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_uint32 *sumtab, l_uint8 *valtab)
scaleToGray3Low()
Definition: scale2.c:1678
PIX * pixScaleToGrayFast(PIX *pixs, l_float32 scalefactor)
pixScaleToGrayFast()
Definition: scale2.c:315
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2298
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:192
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:158
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:182
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:517
static l_uint32 * makeSumTabSG3(void)
makeSumTabSG3()
Definition: scale2.c:1754
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:545
l_int32 pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition: pix2.c:2598
static void scaleToGray4Low(l_uint32 *datad, l_int32 wd, l_int32 hd, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_uint32 *sumtab, l_uint8 *valtab)
scaleToGray4Low()
Definition: scale2.c:1823
static void scaleToGray6Low(l_uint32 *datad, l_int32 wd, l_int32 hd, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 *tab8, l_uint8 *valtab)
scaleToGray6Low()
Definition: scale2.c:1955
PIX * pixScaleGrayLI(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleGrayLI()
Definition: scale1.c:738
static l_uint8 * makeValTabSG3(void)
makeValTabSG3()
Definition: scale2.c:1782
l_int32 pixScaleAndTransferAlpha(PIX *pixd, PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleAndTransferAlpha()
Definition: scale2.c:1357
l_int32 pixSetBorderRingVal(PIX *pixs, l_int32 dist, l_uint32 val)
pixSetBorderRingVal()
Definition: pix2.c:1580
PIX * pixExpandReplicate(PIX *pixs, l_int32 factor)
pixExpandReplicate()
Definition: scale2.c:867
PIX * pixScaleMipmap(PIX *pixs1, PIX *pixs2, l_float32 scale)
pixScaleMipmap()
Definition: scale2.c:810
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:206
#define GET_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:139
static void scaleToGray2Low(l_uint32 *datad, l_int32 wd, l_int32 hd, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_uint32 *sumtab, l_uint8 *valtab)
scaleToGray2Low()
Definition: scale2.c:1534
PIX * pixScaleGrayMinMax2(PIX *pixs, l_int32 type)
pixScaleGrayMinMax2()
Definition: scale2.c:1121
PIX * pixScaleToGray4(PIX *pixs)
pixScaleToGray4()
Definition: scale2.c:497
Definition: pix.h:134
PIX * pixScaleToGray16(PIX *pixs)
pixScaleToGray16()
Definition: scale2.c:649
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:630
static void scaleToGray8Low(l_uint32 *datad, l_int32 wd, l_int32 hd, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 *tab8, l_uint8 *valtab)
scaleToGray8Low()
Definition: scale2.c:2088
PIX * pixResizeToMatch(PIX *pixs, PIX *pixt, l_int32 w, l_int32 h)
pixResizeToMatch()
Definition: pix5.c:1245
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2366
l_int32 pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:729
l_int32 pixGetDimensions(PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1052
static l_uint8 * makeValTabSG8(void)
makeValTabSG8()
Definition: scale2.c:2139
static l_uint8 * makeValTabSG4(void)
makeValTabSG4()
Definition: scale2.c:1901
PIX * pixScaleSmooth(PIX *pix, l_float32 scalex, l_float32 scaley)
pixScaleSmooth()
Definition: scale1.c:1671
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:243
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:216
PIX * pixExpandBinaryReplicate(PIX *pixs, l_int32 xfact, l_int32 yfact)
pixExpandBinaryReplicate()
Definition: binexpand.c:67
PIX * pixScaleToGrayMipmap(PIX *pixs, l_float32 scalefactor)
pixScaleToGrayMipmap()
Definition: scale2.c:722
PIX * pixScaleToGray2(PIX *pixs)
pixScaleToGray2()
Definition: scale2.c:386
static l_int32 scaleMipmapLow(l_uint32 *datad, l_int32 wd, l_int32 hd, l_int32 wpld, l_uint32 *datas1, l_int32 wpls1, l_uint32 *datas2, l_int32 wpls2, l_float32 red)
scaleMipmapLow()
Definition: scale2.c:2253