Leptonica  1.77.0
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  *-----------------------------------------------------------------------*/
1203 PIX *
1205  l_int32 level1,
1206  l_int32 level2,
1207  l_int32 level3,
1208  l_int32 level4)
1209 {
1210 PIX *pixt1, *pixt2, *pixt3, *pixt4;
1211 
1212  PROCNAME("pixScaleGrayRankCascade");
1213 
1214  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1215  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1216  procName, NULL);
1217  if (level1 > 4 || level2 > 4 || level3 > 4 || level4 > 4)
1218  return (PIX *)ERROR_PTR("levels must not exceed 4", procName, NULL);
1219 
1220  if (level1 <= 0) {
1221  L_WARNING("no reduction because level1 not > 0\n", procName);
1222  return pixCopy(NULL, pixs);
1223  }
1224 
1225  pixt1 = pixScaleGrayRank2(pixs, level1);
1226  if (level2 <= 0)
1227  return pixt1;
1228 
1229  pixt2 = pixScaleGrayRank2(pixt1, level2);
1230  pixDestroy(&pixt1);
1231  if (level3 <= 0)
1232  return pixt2;
1233 
1234  pixt3 = pixScaleGrayRank2(pixt2, level3);
1235  pixDestroy(&pixt2);
1236  if (level4 <= 0)
1237  return pixt3;
1238 
1239  pixt4 = pixScaleGrayRank2(pixt3, level4);
1240  pixDestroy(&pixt3);
1241  return pixt4;
1242 }
1243 
1244 
1267 PIX *
1269  l_int32 rank)
1270 {
1271 l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k, m;
1272 l_int32 minval, maxval, rankval, minindex, maxindex;
1273 l_int32 val[4];
1274 l_int32 midval[4]; /* should only use 2 of these */
1275 l_uint32 *datas, *datad, *lines, *lined;
1276 PIX *pixd;
1277 
1278  PROCNAME("pixScaleGrayRank2");
1279 
1280  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1281  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1282  procName, NULL);
1283  if (rank < 1 || rank > 4)
1284  return (PIX *)ERROR_PTR("invalid rank", procName, NULL);
1285 
1286  if (rank == 1)
1287  return pixScaleGrayMinMax2(pixs, L_CHOOSE_MIN);
1288  if (rank == 4)
1289  return pixScaleGrayMinMax2(pixs, L_CHOOSE_MAX);
1290 
1291  pixGetDimensions(pixs, &ws, &hs, NULL);
1292  wd = ws / 2;
1293  hd = hs / 2;
1294  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1295  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1296  pixCopyInputFormat(pixd, pixs);
1297  datas = pixGetData(pixs);
1298  datad = pixGetData(pixd);
1299  wpls = pixGetWpl(pixs);
1300  wpld = pixGetWpl(pixd);
1301  for (i = 0; i < hd; i++) {
1302  lines = datas + 2 * i * wpls;
1303  lined = datad + i * wpld;
1304  for (j = 0; j < wd; j++) {
1305  val[0] = GET_DATA_BYTE(lines, 2 * j);
1306  val[1] = GET_DATA_BYTE(lines, 2 * j + 1);
1307  val[2] = GET_DATA_BYTE(lines + wpls, 2 * j);
1308  val[3] = GET_DATA_BYTE(lines + wpls, 2 * j + 1);
1309  minval = maxval = val[0];
1310  minindex = maxindex = 0;
1311  for (k = 1; k < 4; k++) {
1312  if (val[k] < minval) {
1313  minval = val[k];
1314  minindex = k;
1315  continue;
1316  }
1317  if (val[k] > maxval) {
1318  maxval = val[k];
1319  maxindex = k;
1320  }
1321  }
1322  for (k = 0, m = 0; k < 4; k++) {
1323  if (k == minindex || k == maxindex)
1324  continue;
1325  midval[m++] = val[k];
1326  }
1327  if (m > 2) /* minval == maxval; all val[k] are the same */
1328  rankval = minval;
1329  else if (rank == 2)
1330  rankval = L_MIN(midval[0], midval[1]);
1331  else /* rank == 3 */
1332  rankval = L_MAX(midval[0], midval[1]);
1333  SET_DATA_BYTE(lined, j, rankval);
1334  }
1335  }
1336 
1337  return pixd;
1338 }
1339 
1340 
1341 /*------------------------------------------------------------------------*
1342  * Helper function for transferring alpha with scaling *
1343  *------------------------------------------------------------------------*/
1357 l_ok
1359  PIX *pixs,
1360  l_float32 scalex,
1361  l_float32 scaley)
1362 {
1363 PIX *pix1, *pix2;
1364 
1365  PROCNAME("pixScaleAndTransferAlpha");
1366 
1367  if (!pixs || !pixd)
1368  return ERROR_INT("pixs and pixd not both defined", procName, 1);
1369  if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
1370  return ERROR_INT("pixs not 32 bpp and 4 spp", procName, 1);
1371  if (pixGetDepth(pixd) != 32)
1372  return ERROR_INT("pixd not 32 bpp", procName, 1);
1373 
1374  if (scalex == 1.0 && scaley == 1.0) {
1375  pixCopyRGBComponent(pixd, pixs, L_ALPHA_CHANNEL);
1376  return 0;
1377  }
1378 
1379  pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
1380  pix2 = pixScale(pix1, scalex, scaley);
1381  pixSetRGBComponent(pixd, pix2, L_ALPHA_CHANNEL);
1382  pixDestroy(&pix1);
1383  pixDestroy(&pix2);
1384  return 0;
1385 }
1386 
1387 
1388 /*------------------------------------------------------------------------*
1389  * RGB scaling including alpha (blend) component and gamma transform *
1390  *------------------------------------------------------------------------*/
1435 PIX *
1437  l_float32 scalex,
1438  l_float32 scaley,
1439  PIX *pixg,
1440  l_float32 fract)
1441 {
1442 l_int32 ws, hs, d, spp;
1443 PIX *pixd, *pix32, *pixg2, *pixgs;
1444 
1445  PROCNAME("pixScaleWithAlpha");
1446 
1447  if (!pixs)
1448  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1449  pixGetDimensions(pixs, &ws, &hs, &d);
1450  if (d != 32 && !pixGetColormap(pixs))
1451  return (PIX *)ERROR_PTR("pixs not cmapped or 32 bpp", procName, NULL);
1452  if (scalex <= 0.0 || scaley <= 0.0)
1453  return (PIX *)ERROR_PTR("scale factor <= 0.0", procName, NULL);
1454  if (pixg && pixGetDepth(pixg) != 8) {
1455  L_WARNING("pixg not 8 bpp; using 'fract' transparent alpha\n",
1456  procName);
1457  pixg = NULL;
1458  }
1459  if (!pixg && (fract < 0.0 || fract > 1.0)) {
1460  L_WARNING("invalid fract; using fully opaque\n", procName);
1461  fract = 1.0;
1462  }
1463  if (!pixg && fract == 0.0)
1464  L_WARNING("transparent alpha; image will not be blended\n", procName);
1465 
1466  /* Make sure input to scaling is 32 bpp rgb, and scale it */
1467  if (d != 32)
1468  pix32 = pixConvertTo32(pixs);
1469  else
1470  pix32 = pixClone(pixs);
1471  spp = pixGetSpp(pix32);
1472  pixSetSpp(pix32, 3); /* ignore the alpha channel for scaling */
1473  pixd = pixScale(pix32, scalex, scaley);
1474  pixSetSpp(pix32, spp); /* restore initial value in case it's a clone */
1475  pixDestroy(&pix32);
1476 
1477  /* Set up alpha layer with a fading border and scale it */
1478  if (!pixg) {
1479  pixg2 = pixCreate(ws, hs, 8);
1480  if (fract == 1.0)
1481  pixSetAll(pixg2);
1482  else if (fract > 0.0)
1483  pixSetAllArbitrary(pixg2, (l_int32)(255.0 * fract));
1484  } else {
1485  pixg2 = pixResizeToMatch(pixg, NULL, ws, hs);
1486  }
1487  if (ws > 10 && hs > 10) { /* see note 4 */
1488  pixSetBorderRingVal(pixg2, 1,
1489  (l_int32)(255.0 * fract * AlphaMaskBorderVals[0]));
1490  pixSetBorderRingVal(pixg2, 2,
1491  (l_int32)(255.0 * fract * AlphaMaskBorderVals[1]));
1492  }
1493  pixgs = pixScaleGeneral(pixg2, scalex, scaley, 0.0, 0);
1494 
1495  /* Combine into a 4 spp result */
1496  pixSetRGBComponent(pixd, pixgs, L_ALPHA_CHANNEL);
1497  pixCopyInputFormat(pixd, pixs);
1498 
1499  pixDestroy(&pixg2);
1500  pixDestroy(&pixgs);
1501  return pixd;
1502 }
1503 
1504 
1505 /* ================================================================ *
1506  * Low level static functions *
1507  * ================================================================ */
1508 
1509 /*------------------------------------------------------------------*
1510  * Scale-to-gray 2x *
1511  *------------------------------------------------------------------*/
1534 static void
1535 scaleToGray2Low(l_uint32 *datad,
1536  l_int32 wd,
1537  l_int32 hd,
1538  l_int32 wpld,
1539  l_uint32 *datas,
1540  l_int32 wpls,
1541  l_uint32 *sumtab,
1542  l_uint8 *valtab)
1543 {
1544 l_int32 i, j, l, k, m, wd4, extra;
1545 l_uint32 sbyte1, sbyte2, sum;
1546 l_uint32 *lines, *lined;
1547 
1548  /* i indexes the dest lines
1549  * l indexes the source lines
1550  * j indexes the dest bytes
1551  * k indexes the source bytes
1552  * We take two bytes from the source (in 2 lines of 8 pixels
1553  * each) and convert them into four 8 bpp bytes of the dest. */
1554  wd4 = wd & 0xfffffffc;
1555  extra = wd - wd4;
1556  for (i = 0, l = 0; i < hd; i++, l += 2) {
1557  lines = datas + l * wpls;
1558  lined = datad + i * wpld;
1559  for (j = 0, k = 0; j < wd4; j += 4, k++) {
1560  sbyte1 = GET_DATA_BYTE(lines, k);
1561  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1562  sum = sumtab[sbyte1] + sumtab[sbyte2];
1563  SET_DATA_BYTE(lined, j, valtab[sum >> 24]);
1564  SET_DATA_BYTE(lined, j + 1, valtab[(sum >> 16) & 0xff]);
1565  SET_DATA_BYTE(lined, j + 2, valtab[(sum >> 8) & 0xff]);
1566  SET_DATA_BYTE(lined, j + 3, valtab[sum & 0xff]);
1567  }
1568  if (extra > 0) {
1569  sbyte1 = GET_DATA_BYTE(lines, k);
1570  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1571  sum = sumtab[sbyte1] + sumtab[sbyte2];
1572  for (m = 0; m < extra; m++) {
1573  SET_DATA_BYTE(lined, j + m,
1574  valtab[((sum >> (24 - 8 * m)) & 0xff)]);
1575  }
1576  }
1577 
1578  }
1579 
1580  return;
1581 }
1582 
1583 
1593 static l_uint32 *
1595 {
1596 l_int32 i;
1597 l_int32 sum[] = {0, 1, 1, 2};
1598 l_uint32 *tab;
1599 
1600  PROCNAME("makeSumTabSG2");
1601 
1602  if ((tab = (l_uint32 *)LEPT_CALLOC(256, sizeof(l_uint32))) == NULL)
1603  return (l_uint32 *)ERROR_PTR("tab not made", procName, NULL);
1604 
1605  /* Pack the four sums separately in four bytes */
1606  for (i = 0; i < 256; i++) {
1607  tab[i] = (sum[i & 0x3] | sum[(i >> 2) & 0x3] << 8 |
1608  sum[(i >> 4) & 0x3] << 16 | sum[(i >> 6) & 0x3] << 24);
1609  }
1610  return tab;
1611 }
1612 
1613 
1624 static l_uint8 *
1626 {
1627 l_int32 i;
1628 l_uint8 *tab;
1629 
1630  PROCNAME("makeValTabSG2");
1631 
1632  if ((tab = (l_uint8 *)LEPT_CALLOC(5, sizeof(l_uint8))) == NULL)
1633  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
1634  for (i = 0; i < 5; i++)
1635  tab[i] = 255 - (i * 255) / 4;
1636  return tab;
1637 }
1638 
1639 
1640 /*------------------------------------------------------------------*
1641  * Scale-to-gray 3x *
1642  *------------------------------------------------------------------*/
1678 static void
1679 scaleToGray3Low(l_uint32 *datad,
1680  l_int32 wd,
1681  l_int32 hd,
1682  l_int32 wpld,
1683  l_uint32 *datas,
1684  l_int32 wpls,
1685  l_uint32 *sumtab,
1686  l_uint8 *valtab)
1687 {
1688 l_int32 i, j, l, k;
1689 l_uint32 threebytes1, threebytes2, threebytes3, sum;
1690 l_uint32 *lines, *lined;
1691 
1692  /* i indexes the dest lines
1693  * l indexes the source lines
1694  * j indexes the dest bytes
1695  * k indexes the source bytes
1696  * We take 9 bytes from the source (72 binary pixels
1697  * in three lines of 24 pixels each) and convert it
1698  * into 8 bytes of the dest (8 8bpp pixels in one line) */
1699  for (i = 0, l = 0; i < hd; i++, l += 3) {
1700  lines = datas + l * wpls;
1701  lined = datad + i * wpld;
1702  for (j = 0, k = 0; j < wd; j += 8, k += 3) {
1703  threebytes1 = (GET_DATA_BYTE(lines, k) << 16) |
1704  (GET_DATA_BYTE(lines, k + 1) << 8) |
1705  GET_DATA_BYTE(lines, k + 2);
1706  threebytes2 = (GET_DATA_BYTE(lines + wpls, k) << 16) |
1707  (GET_DATA_BYTE(lines + wpls, k + 1) << 8) |
1708  GET_DATA_BYTE(lines + wpls, k + 2);
1709  threebytes3 = (GET_DATA_BYTE(lines + 2 * wpls, k) << 16) |
1710  (GET_DATA_BYTE(lines + 2 * wpls, k + 1) << 8) |
1711  GET_DATA_BYTE(lines + 2 * wpls, k + 2);
1712 
1713  sum = sumtab[(threebytes1 >> 18)] +
1714  sumtab[(threebytes2 >> 18)] +
1715  sumtab[(threebytes3 >> 18)];
1716  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 2)]);
1717  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1718 
1719  sum = sumtab[((threebytes1 >> 12) & 0x3f)] +
1720  sumtab[((threebytes2 >> 12) & 0x3f)] +
1721  sumtab[((threebytes3 >> 12) & 0x3f)];
1722  SET_DATA_BYTE(lined, j + 2, valtab[GET_DATA_BYTE(&sum, 2)]);
1723  SET_DATA_BYTE(lined, j + 3, valtab[GET_DATA_BYTE(&sum, 3)]);
1724 
1725  sum = sumtab[((threebytes1 >> 6) & 0x3f)] +
1726  sumtab[((threebytes2 >> 6) & 0x3f)] +
1727  sumtab[((threebytes3 >> 6) & 0x3f)];
1728  SET_DATA_BYTE(lined, j + 4, valtab[GET_DATA_BYTE(&sum, 2)]);
1729  SET_DATA_BYTE(lined, j + 5, valtab[GET_DATA_BYTE(&sum, 3)]);
1730 
1731  sum = sumtab[(threebytes1 & 0x3f)] +
1732  sumtab[(threebytes2 & 0x3f)] +
1733  sumtab[(threebytes3 & 0x3f)];
1734  SET_DATA_BYTE(lined, j + 6, valtab[GET_DATA_BYTE(&sum, 2)]);
1735  SET_DATA_BYTE(lined, j + 7, valtab[GET_DATA_BYTE(&sum, 3)]);
1736  }
1737  }
1738 
1739  return;
1740 }
1741 
1742 
1743 
1754 static l_uint32 *
1756 {
1757 l_int32 i;
1758 l_int32 sum[] = {0, 1, 1, 2, 1, 2, 2, 3};
1759 l_uint32 *tab;
1760 
1761  PROCNAME("makeSumTabSG3");
1762 
1763  if ((tab = (l_uint32 *)LEPT_CALLOC(64, sizeof(l_uint32))) == NULL)
1764  return (l_uint32 *)ERROR_PTR("tab not made", procName, NULL);
1765 
1766  /* Pack the two sums separately in two bytes */
1767  for (i = 0; i < 64; i++) {
1768  tab[i] = (sum[i & 0x07]) | (sum[(i >> 3) & 0x07] << 8);
1769  }
1770  return tab;
1771 }
1772 
1773 
1782 static l_uint8 *
1784 {
1785 l_int32 i;
1786 l_uint8 *tab;
1787 
1788  PROCNAME("makeValTabSG3");
1789 
1790  if ((tab = (l_uint8 *)LEPT_CALLOC(10, sizeof(l_uint8))) == NULL)
1791  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
1792  for (i = 0; i < 10; i++)
1793  tab[i] = 0xff - (i * 255) / 9;
1794  return tab;
1795 }
1796 
1797 
1798 /*------------------------------------------------------------------*
1799  * Scale-to-gray 4x *
1800  *------------------------------------------------------------------*/
1823 static void
1824 scaleToGray4Low(l_uint32 *datad,
1825  l_int32 wd,
1826  l_int32 hd,
1827  l_int32 wpld,
1828  l_uint32 *datas,
1829  l_int32 wpls,
1830  l_uint32 *sumtab,
1831  l_uint8 *valtab)
1832 {
1833 l_int32 i, j, l, k;
1834 l_uint32 sbyte1, sbyte2, sbyte3, sbyte4, sum;
1835 l_uint32 *lines, *lined;
1836 
1837  /* i indexes the dest lines
1838  * l indexes the source lines
1839  * j indexes the dest bytes
1840  * k indexes the source bytes
1841  * We take four bytes from the source (in 4 lines of 8 pixels
1842  * each) and convert it into two 8 bpp bytes of the dest. */
1843  for (i = 0, l = 0; i < hd; i++, l += 4) {
1844  lines = datas + l * wpls;
1845  lined = datad + i * wpld;
1846  for (j = 0, k = 0; j < wd; j += 2, k++) {
1847  sbyte1 = GET_DATA_BYTE(lines, k);
1848  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1849  sbyte3 = GET_DATA_BYTE(lines + 2 * wpls, k);
1850  sbyte4 = GET_DATA_BYTE(lines + 3 * wpls, k);
1851  sum = sumtab[sbyte1] + sumtab[sbyte2] +
1852  sumtab[sbyte3] + sumtab[sbyte4];
1853  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 2)]);
1854  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1855  }
1856  }
1857 
1858  return;
1859 }
1860 
1861 
1871 static l_uint32 *
1873 {
1874 l_int32 i;
1875 l_int32 sum[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1876 l_uint32 *tab;
1877 
1878  PROCNAME("makeSumTabSG4");
1879 
1880  if ((tab = (l_uint32 *)LEPT_CALLOC(256, sizeof(l_uint32))) == NULL)
1881  return (l_uint32 *)ERROR_PTR("tab not made", procName, NULL);
1882 
1883  /* Pack the two sums separately in two bytes */
1884  for (i = 0; i < 256; i++) {
1885  tab[i] = (sum[i & 0xf]) | (sum[(i >> 4) & 0xf] << 8);
1886  }
1887  return tab;
1888 }
1889 
1890 
1901 static l_uint8 *
1903 {
1904 l_int32 i;
1905 l_uint8 *tab;
1906 
1907  PROCNAME("makeValTabSG4");
1908 
1909  if ((tab = (l_uint8 *)LEPT_CALLOC(17, sizeof(l_uint8))) == NULL)
1910  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
1911  for (i = 0; i < 17; i++)
1912  tab[i] = 0xff - (i * 255) / 16;
1913  return tab;
1914 }
1915 
1916 
1917 /*------------------------------------------------------------------*
1918  * Scale-to-gray 6x *
1919  *------------------------------------------------------------------*/
1955 static void
1956 scaleToGray6Low(l_uint32 *datad,
1957  l_int32 wd,
1958  l_int32 hd,
1959  l_int32 wpld,
1960  l_uint32 *datas,
1961  l_int32 wpls,
1962  l_int32 *tab8,
1963  l_uint8 *valtab)
1964 {
1965 l_int32 i, j, l, k;
1966 l_uint32 threebytes1, threebytes2, threebytes3;
1967 l_uint32 threebytes4, threebytes5, threebytes6, sum;
1968 l_uint32 *lines, *lined;
1969 
1970  /* i indexes the dest lines
1971  * l indexes the source lines
1972  * j indexes the dest bytes
1973  * k indexes the source bytes
1974  * We take 18 bytes from the source (144 binary pixels
1975  * in six lines of 24 pixels each) and convert it
1976  * into 4 bytes of the dest (four 8 bpp pixels in one line) */
1977  for (i = 0, l = 0; i < hd; i++, l += 6) {
1978  lines = datas + l * wpls;
1979  lined = datad + i * wpld;
1980  for (j = 0, k = 0; j < wd; j += 4, k += 3) {
1981  /* First grab the 18 bytes, 3 at a time, and put each set
1982  * of 3 bytes into the LS bytes of a 32-bit word. */
1983  threebytes1 = (GET_DATA_BYTE(lines, k) << 16) |
1984  (GET_DATA_BYTE(lines, k + 1) << 8) |
1985  GET_DATA_BYTE(lines, k + 2);
1986  threebytes2 = (GET_DATA_BYTE(lines + wpls, k) << 16) |
1987  (GET_DATA_BYTE(lines + wpls, k + 1) << 8) |
1988  GET_DATA_BYTE(lines + wpls, k + 2);
1989  threebytes3 = (GET_DATA_BYTE(lines + 2 * wpls, k) << 16) |
1990  (GET_DATA_BYTE(lines + 2 * wpls, k + 1) << 8) |
1991  GET_DATA_BYTE(lines + 2 * wpls, k + 2);
1992  threebytes4 = (GET_DATA_BYTE(lines + 3 * wpls, k) << 16) |
1993  (GET_DATA_BYTE(lines + 3 * wpls, k + 1) << 8) |
1994  GET_DATA_BYTE(lines + 3 * wpls, k + 2);
1995  threebytes5 = (GET_DATA_BYTE(lines + 4 * wpls, k) << 16) |
1996  (GET_DATA_BYTE(lines + 4 * wpls, k + 1) << 8) |
1997  GET_DATA_BYTE(lines + 4 * wpls, k + 2);
1998  threebytes6 = (GET_DATA_BYTE(lines + 5 * wpls, k) << 16) |
1999  (GET_DATA_BYTE(lines + 5 * wpls, k + 1) << 8) |
2000  GET_DATA_BYTE(lines + 5 * wpls, k + 2);
2001 
2002  /* Sum first set of 36 bits and convert to 0-255 */
2003  sum = tab8[(threebytes1 >> 18)] +
2004  tab8[(threebytes2 >> 18)] +
2005  tab8[(threebytes3 >> 18)] +
2006  tab8[(threebytes4 >> 18)] +
2007  tab8[(threebytes5 >> 18)] +
2008  tab8[(threebytes6 >> 18)];
2009  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 3)]);
2010 
2011  /* Ditto for second set */
2012  sum = tab8[((threebytes1 >> 12) & 0x3f)] +
2013  tab8[((threebytes2 >> 12) & 0x3f)] +
2014  tab8[((threebytes3 >> 12) & 0x3f)] +
2015  tab8[((threebytes4 >> 12) & 0x3f)] +
2016  tab8[((threebytes5 >> 12) & 0x3f)] +
2017  tab8[((threebytes6 >> 12) & 0x3f)];
2018  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
2019 
2020  sum = tab8[((threebytes1 >> 6) & 0x3f)] +
2021  tab8[((threebytes2 >> 6) & 0x3f)] +
2022  tab8[((threebytes3 >> 6) & 0x3f)] +
2023  tab8[((threebytes4 >> 6) & 0x3f)] +
2024  tab8[((threebytes5 >> 6) & 0x3f)] +
2025  tab8[((threebytes6 >> 6) & 0x3f)];
2026  SET_DATA_BYTE(lined, j + 2, valtab[GET_DATA_BYTE(&sum, 3)]);
2027 
2028  sum = tab8[(threebytes1 & 0x3f)] +
2029  tab8[(threebytes2 & 0x3f)] +
2030  tab8[(threebytes3 & 0x3f)] +
2031  tab8[(threebytes4 & 0x3f)] +
2032  tab8[(threebytes5 & 0x3f)] +
2033  tab8[(threebytes6 & 0x3f)];
2034  SET_DATA_BYTE(lined, j + 3, valtab[GET_DATA_BYTE(&sum, 3)]);
2035  }
2036  }
2037  return;
2038 }
2039 
2040 
2049 static l_uint8 *
2051 {
2052 l_int32 i;
2053 l_uint8 *tab;
2054 
2055  PROCNAME("makeValTabSG6");
2056 
2057  if ((tab = (l_uint8 *)LEPT_CALLOC(37, sizeof(l_uint8))) == NULL)
2058  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
2059  for (i = 0; i < 37; i++)
2060  tab[i] = 0xff - (i * 255) / 36;
2061  return tab;
2062 }
2063 
2064 
2065 /*------------------------------------------------------------------*
2066  * Scale-to-gray 8x *
2067  *------------------------------------------------------------------*/
2088 static void
2089 scaleToGray8Low(l_uint32 *datad,
2090  l_int32 wd,
2091  l_int32 hd,
2092  l_int32 wpld,
2093  l_uint32 *datas,
2094  l_int32 wpls,
2095  l_int32 *tab8,
2096  l_uint8 *valtab)
2097 {
2098 l_int32 i, j, k;
2099 l_int32 sbyte0, sbyte1, sbyte2, sbyte3, sbyte4, sbyte5, sbyte6, sbyte7, sum;
2100 l_uint32 *lines, *lined;
2101 
2102  /* i indexes the dest lines
2103  * k indexes the source lines
2104  * j indexes the src and dest bytes
2105  * We take 8 bytes from the source (in 8 lines of 8 pixels
2106  * each) and convert it into one 8 bpp byte of the dest. */
2107  for (i = 0, k = 0; i < hd; i++, k += 8) {
2108  lines = datas + k * wpls;
2109  lined = datad + i * wpld;
2110  for (j = 0; j < wd; j++) {
2111  sbyte0 = GET_DATA_BYTE(lines, j);
2112  sbyte1 = GET_DATA_BYTE(lines + wpls, j);
2113  sbyte2 = GET_DATA_BYTE(lines + 2 * wpls, j);
2114  sbyte3 = GET_DATA_BYTE(lines + 3 * wpls, j);
2115  sbyte4 = GET_DATA_BYTE(lines + 4 * wpls, j);
2116  sbyte5 = GET_DATA_BYTE(lines + 5 * wpls, j);
2117  sbyte6 = GET_DATA_BYTE(lines + 6 * wpls, j);
2118  sbyte7 = GET_DATA_BYTE(lines + 7 * wpls, j);
2119  sum = tab8[sbyte0] + tab8[sbyte1] +
2120  tab8[sbyte2] + tab8[sbyte3] +
2121  tab8[sbyte4] + tab8[sbyte5] +
2122  tab8[sbyte6] + tab8[sbyte7];
2123  SET_DATA_BYTE(lined, j, valtab[sum]);
2124  }
2125  }
2126 
2127  return;
2128 }
2129 
2130 
2139 static l_uint8 *
2141 {
2142 l_int32 i;
2143 l_uint8 *tab;
2144 
2145  PROCNAME("makeValTabSG8");
2146 
2147  if ((tab = (l_uint8 *)LEPT_CALLOC(65, sizeof(l_uint8))) == NULL)
2148  return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
2149  for (i = 0; i < 65; i++)
2150  tab[i] = 0xff - (i * 255) / 64;
2151  return tab;
2152 }
2153 
2154 
2155 /*------------------------------------------------------------------*
2156  * Scale-to-gray 16x *
2157  *------------------------------------------------------------------*/
2177 static void
2178 scaleToGray16Low(l_uint32 *datad,
2179  l_int32 wd,
2180  l_int32 hd,
2181  l_int32 wpld,
2182  l_uint32 *datas,
2183  l_int32 wpls,
2184  l_int32 *tab8)
2185 {
2186 l_int32 i, j, k, m;
2187 l_int32 sum;
2188 l_uint32 *lines, *lined;
2189 
2190  /* i indexes the dest lines
2191  * k indexes the source lines
2192  * j indexes the dest bytes
2193  * m indexes the src bytes
2194  * We take 32 bytes from the source (in 16 lines of 16 pixels
2195  * each) and convert it into one 8 bpp byte of the dest. */
2196  for (i = 0, k = 0; i < hd; i++, k += 16) {
2197  lines = datas + k * wpls;
2198  lined = datad + i * wpld;
2199  for (j = 0; j < wd; j++) {
2200  m = 2 * j;
2201  sum = tab8[GET_DATA_BYTE(lines, m)];
2202  sum += tab8[GET_DATA_BYTE(lines, m + 1)];
2203  sum += tab8[GET_DATA_BYTE(lines + wpls, m)];
2204  sum += tab8[GET_DATA_BYTE(lines + wpls, m + 1)];
2205  sum += tab8[GET_DATA_BYTE(lines + 2 * wpls, m)];
2206  sum += tab8[GET_DATA_BYTE(lines + 2 * wpls, m + 1)];
2207  sum += tab8[GET_DATA_BYTE(lines + 3 * wpls, m)];
2208  sum += tab8[GET_DATA_BYTE(lines + 3 * wpls, m + 1)];
2209  sum += tab8[GET_DATA_BYTE(lines + 4 * wpls, m)];
2210  sum += tab8[GET_DATA_BYTE(lines + 4 * wpls, m + 1)];
2211  sum += tab8[GET_DATA_BYTE(lines + 5 * wpls, m)];
2212  sum += tab8[GET_DATA_BYTE(lines + 5 * wpls, m + 1)];
2213  sum += tab8[GET_DATA_BYTE(lines + 6 * wpls, m)];
2214  sum += tab8[GET_DATA_BYTE(lines + 6 * wpls, m + 1)];
2215  sum += tab8[GET_DATA_BYTE(lines + 7 * wpls, m)];
2216  sum += tab8[GET_DATA_BYTE(lines + 7 * wpls, m + 1)];
2217  sum += tab8[GET_DATA_BYTE(lines + 8 * wpls, m)];
2218  sum += tab8[GET_DATA_BYTE(lines + 8 * wpls, m + 1)];
2219  sum += tab8[GET_DATA_BYTE(lines + 9 * wpls, m)];
2220  sum += tab8[GET_DATA_BYTE(lines + 9 * wpls, m + 1)];
2221  sum += tab8[GET_DATA_BYTE(lines + 10 * wpls, m)];
2222  sum += tab8[GET_DATA_BYTE(lines + 10 * wpls, m + 1)];
2223  sum += tab8[GET_DATA_BYTE(lines + 11 * wpls, m)];
2224  sum += tab8[GET_DATA_BYTE(lines + 11 * wpls, m + 1)];
2225  sum += tab8[GET_DATA_BYTE(lines + 12 * wpls, m)];
2226  sum += tab8[GET_DATA_BYTE(lines + 12 * wpls, m + 1)];
2227  sum += tab8[GET_DATA_BYTE(lines + 13 * wpls, m)];
2228  sum += tab8[GET_DATA_BYTE(lines + 13 * wpls, m + 1)];
2229  sum += tab8[GET_DATA_BYTE(lines + 14 * wpls, m)];
2230  sum += tab8[GET_DATA_BYTE(lines + 14 * wpls, m + 1)];
2231  sum += tab8[GET_DATA_BYTE(lines + 15 * wpls, m)];
2232  sum += tab8[GET_DATA_BYTE(lines + 15 * wpls, m + 1)];
2233  sum = L_MIN(sum, 255);
2234  SET_DATA_BYTE(lined, j, 255 - sum);
2235  }
2236  }
2237 
2238  return;
2239 }
2240 
2241 
2242 
2243 /*------------------------------------------------------------------*
2244  * Grayscale mipmap *
2245  *------------------------------------------------------------------*/
2253 static l_int32
2254 scaleMipmapLow(l_uint32 *datad,
2255  l_int32 wd,
2256  l_int32 hd,
2257  l_int32 wpld,
2258  l_uint32 *datas1,
2259  l_int32 wpls1,
2260  l_uint32 *datas2,
2261  l_int32 wpls2,
2262  l_float32 red)
2263 {
2264 l_int32 i, j, val1, val2, val, row2, col2;
2265 l_int32 *srow, *scol;
2266 l_uint32 *lines1, *lines2, *lined;
2267 l_float32 ratio, w1, w2;
2268 
2269  PROCNAME("scaleMipmapLow");
2270 
2271  /* Clear dest */
2272  memset(datad, 0, 4LL * wpld * hd);
2273 
2274  /* Each dest pixel at (j,i) is computed by interpolating
2275  between the two src images at the corresponding location.
2276  We store the UL corner locations of the square of
2277  src pixels in thelower-resolution image that correspond
2278  to dest pixel (j,i). The are labeled by the arrays
2279  srow[i], scol[j]. The UL corner locations of the higher
2280  resolution src pixels are obtained from these arrays
2281  by multiplying by 2. */
2282  if ((srow = (l_int32 *)LEPT_CALLOC(hd, sizeof(l_int32))) == NULL)
2283  return ERROR_INT("srow not made", procName, 1);
2284  if ((scol = (l_int32 *)LEPT_CALLOC(wd, sizeof(l_int32))) == NULL) {
2285  LEPT_FREE(srow);
2286  return ERROR_INT("scol not made", procName, 1);
2287  }
2288  ratio = 1. / (2. * red); /* 0.5 for red = 1, 1 for red = 0.5 */
2289  for (i = 0; i < hd; i++)
2290  srow[i] = (l_int32)(ratio * i);
2291  for (j = 0; j < wd; j++)
2292  scol[j] = (l_int32)(ratio * j);
2293 
2294  /* Get weights for linear interpolation: these are the
2295  * 'distances' of the dest image plane from the two
2296  * src image planes. */
2297  w1 = 2. * red - 1.; /* w1 --> 1 as red --> 1 */
2298  w2 = 1. - w1;
2299 
2300  /* For each dest pixel, compute linear interpolation */
2301  for (i = 0; i < hd; i++) {
2302  row2 = srow[i];
2303  lines1 = datas1 + 2 * row2 * wpls1;
2304  lines2 = datas2 + row2 * wpls2;
2305  lined = datad + i * wpld;
2306  for (j = 0; j < wd; j++) {
2307  col2 = scol[j];
2308  val1 = GET_DATA_BYTE(lines1, 2 * col2);
2309  val2 = GET_DATA_BYTE(lines2, col2);
2310  val = (l_int32)(w1 * val1 + w2 * val2);
2311  SET_DATA_BYTE(lined, j, val);
2312  }
2313  }
2314 
2315  LEPT_FREE(srow);
2316  LEPT_FREE(scol);
2317  return 0;
2318 }
l_ok pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition: pix2.c:2610
PIX * pixScaleWithAlpha(PIX *pixs, l_float32 scalex, l_float32 scaley, PIX *pixg, l_float32 fract)
pixScaleWithAlpha()
Definition: scale2.c:1436
static l_uint8 * makeValTabSG2(void)
makeValTabSG2()
Definition: scale2.c:1625
l_ok pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition: pix2.c:2463
PIX * pixScaleToGray(PIX *pixs, l_float32 scalefactor)
pixScaleToGray()
Definition: scale2.c:204
static l_uint32 * makeSumTabSG4(void)
makeSumTabSG4()
Definition: scale2.c:1872
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:1204
PIX * pixScaleGrayMinMax(PIX *pixs, l_int32 xfact, l_int32 yfact, l_int32 type)
pixScaleGrayMinMax()
Definition: scale2.c:1014
PIX * pixScaleGrayRank2(PIX *pixs, l_int32 rank)
pixScaleGrayRank2()
Definition: scale2.c:1268
static l_uint8 * makeValTabSG6(void)
makeValTabSG6()
Definition: scale2.c:2050
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:1594
PIX * pixScaleGeneral(PIX *pixs, l_float32 scalex, l_float32 scaley, l_float32 sharpfract, l_int32 sharpwidth)
pixScaleGeneral()
Definition: scale1.c:414
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:741
PIX * pixScaleToGray6(PIX *pixs)
pixScaleToGray6()
Definition: scale2.c:552
#define SET_DATA_QBIT(pdata, n, val)
Definition: arrayaccess.h:168
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1624
PIX * pixScaleToGray3(PIX *pixs)
pixScaleToGray3()
Definition: scale2.c:443
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition: pix2.c:2404
#define SET_DATA_DIBIT(pdata, n, val)
Definition: arrayaccess.h:149
PIX * pixScaleToGray8(PIX *pixs)
pixScaleToGray8()
Definition: scale2.c:600
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:876
PIX * pixScaleBinary(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBinary()
Definition: scale1.c:2145
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:2178
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:1679
PIX * pixScaleToGrayFast(PIX *pixs, l_float32 scalefactor)
pixScaleToGrayFast()
Definition: scale2.c:315
l_ok pixSetBorderRingVal(PIX *pixs, l_int32 dist, l_uint32 val)
pixSetBorderRingVal()
Definition: pix2.c:1592
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2297
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:164
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:515
static l_uint32 * makeSumTabSG3(void)
makeSumTabSG3()
Definition: scale2.c:1755
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
l_ok pixCopyColormap(PIX *pixd, PIX *pixs)
pixCopyColormap()
Definition: pix1.c:745
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
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:1824
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:1956
PIX * pixScaleGrayLI(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleGrayLI()
Definition: scale1.c:778
static l_uint8 * makeValTabSG3(void)
makeValTabSG3()
Definition: scale2.c:1783
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:212
#define GET_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:145
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:1535
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:628
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:2089
PIX * pixResizeToMatch(PIX *pixs, PIX *pixt, l_int32 w, l_int32 h)
pixResizeToMatch()
Definition: pix5.c:1252
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2366
static l_uint8 * makeValTabSG8(void)
makeValTabSG8()
Definition: scale2.c:2140
static l_uint8 * makeValTabSG4(void)
makeValTabSG4()
Definition: scale2.c:1902
PIX * pixScaleSmooth(PIX *pix, l_float32 scalex, l_float32 scaley)
pixScaleSmooth()
Definition: scale1.c:1711
l_ok pixScaleAndTransferAlpha(PIX *pixd, PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleAndTransferAlpha()
Definition: scale2.c:1358
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:244
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
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:2254