Leptonica  1.83.1
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 #ifdef HAVE_CONFIG_H
99 #include <config_auto.h>
100 #endif /* HAVE_CONFIG_H */
101 
102 #include <string.h>
103 #include "allheaders.h"
104 
105 static void scaleToGray2Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
106  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
107  l_uint32 *sumtab, l_uint8 *valtab);
108 static l_uint32 *makeSumTabSG2(void);
109 static l_uint8 *makeValTabSG2(void);
110 static void scaleToGray3Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
111  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
112  l_uint32 *sumtab, l_uint8 *valtab);
113 static l_uint32 *makeSumTabSG3(void);
114 static l_uint8 *makeValTabSG3(void);
115 static void scaleToGray4Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
116  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
117  l_uint32 *sumtab, l_uint8 *valtab);
118 static l_uint32 *makeSumTabSG4(void);
119 static l_uint8 *makeValTabSG4(void);
120 static void scaleToGray6Low(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 *makeValTabSG6(void);
124 static void scaleToGray8Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
125  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
126  l_int32 *tab8, l_uint8 *valtab);
127 static l_uint8 *makeValTabSG8(void);
128 static void scaleToGray16Low(l_uint32 *datad, l_int32 wd, l_int32 hd,
129  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
130  l_int32 *tab8);
131 static l_int32 scaleMipmapLow(l_uint32 *datad, l_int32 wd, l_int32 hd,
132  l_int32 wpld, l_uint32 *datas1, l_int32 wpls1,
133  l_uint32 *datas2, l_int32 wpls2, l_float32 red);
134 
135 extern l_float32 AlphaMaskBorderVals[2];
136 
137 
138 /*------------------------------------------------------------------*
139  * Scale-to-gray (1 bpp --> 8 bpp; arbitrary downscaling) *
140  *------------------------------------------------------------------*/
207 PIX *
209  l_float32 scalefactor)
210 {
211 l_int32 w, h, minsrc, mindest;
212 l_float32 mag, red;
213 PIX *pixt, *pixd;
214 
215  if (!pixs)
216  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
217  if (pixGetDepth(pixs) != 1)
218  return (PIX *)ERROR_PTR("pixs not 1 bpp", __func__, NULL);
219  if (scalefactor <= 0.0)
220  return (PIX *)ERROR_PTR("scalefactor <= 0.0", __func__, NULL);
221  if (scalefactor >= 1.0)
222  return (PIX *)ERROR_PTR("scalefactor >= 1.0", __func__, NULL);
223  pixGetDimensions(pixs, &w, &h, NULL);
224  minsrc = L_MIN(w, h);
225  mindest = (l_int32)((l_float32)minsrc * scalefactor);
226  if (mindest < 2)
227  return (PIX *)ERROR_PTR("scalefactor too small", __func__, NULL);
228 
229  if (scalefactor > 0.5) { /* see note (5) */
230  mag = 2.0 * scalefactor; /* will be < 2.0 */
231 /* lept_stderr("2x with mag %7.3f\n", mag); */
232  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
233  return (PIX *)ERROR_PTR("pixt not made", __func__, NULL);
234  pixd = pixScaleToGray2(pixt);
235  } else if (scalefactor == 0.5) {
236  return pixd = pixScaleToGray2(pixs);
237  } else if (scalefactor > 0.33333) { /* see note (5) */
238  mag = 3.0 * scalefactor; /* will be < 1.5 */
239 /* lept_stderr("3x with mag %7.3f\n", mag); */
240  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
241  return (PIX *)ERROR_PTR("pixt not made", __func__, NULL);
242  pixd = pixScaleToGray3(pixt);
243  } else if (scalefactor > 0.25) { /* see note (5) */
244  mag = 4.0 * scalefactor; /* will be < 1.3333 */
245 /* lept_stderr("4x with mag %7.3f\n", mag); */
246  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
247  return (PIX *)ERROR_PTR("pixt not made", __func__, NULL);
248  pixd = pixScaleToGray4(pixt);
249  } else if (scalefactor == 0.25) {
250  return pixd = pixScaleToGray4(pixs);
251  } else if (scalefactor > 0.16667) { /* see note (5) */
252  mag = 6.0 * scalefactor; /* will be < 1.5 */
253 /* lept_stderr("6x with mag %7.3f\n", mag); */
254  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
255  return (PIX *)ERROR_PTR("pixt not made", __func__, NULL);
256  pixd = pixScaleToGray6(pixt);
257  } else if (scalefactor == 0.16667) {
258  return pixd = pixScaleToGray6(pixs);
259  } else if (scalefactor > 0.125) { /* see note (5) */
260  mag = 8.0 * scalefactor; /* will be < 1.3333 */
261 /* lept_stderr("8x with mag %7.3f\n", mag); */
262  if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
263  return (PIX *)ERROR_PTR("pixt not made", __func__, NULL);
264  pixd = pixScaleToGray8(pixt);
265  } else if (scalefactor == 0.125) {
266  return pixd = pixScaleToGray8(pixs);
267  } else if (scalefactor > 0.0625) { /* see note (6) */
268  red = 8.0 * scalefactor; /* will be > 0.5 */
269 /* lept_stderr("8x with red %7.3f\n", red); */
270  if ((pixt = pixScaleBinary(pixs, red, red)) == NULL)
271  return (PIX *)ERROR_PTR("pixt not made", __func__, NULL);
272  pixd = pixScaleToGray8(pixt);
273  } else if (scalefactor == 0.0625) {
274  return pixd = pixScaleToGray16(pixs);
275  } else { /* see note (7) */
276  red = 16.0 * scalefactor; /* will be <= 1.0 */
277 /* lept_stderr("16x with red %7.3f\n", red); */
278  if ((pixt = pixScaleToGray16(pixs)) == NULL)
279  return (PIX *)ERROR_PTR("pixt not made", __func__, NULL);
280  if (red < 0.7)
281  pixd = pixScaleSmooth(pixt, red, red); /* see note (3) */
282  else
283  pixd = pixScaleGrayLI(pixt, red, red); /* see note (2) */
284  }
285 
286  pixDestroy(&pixt);
287  if (!pixd)
288  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
289  pixCopyInputFormat(pixd, pixs);
290  return pixd;
291 }
292 
293 
316 PIX *
318  l_float32 scalefactor)
319 {
320 l_int32 w, h, minsrc, mindest;
321 l_float32 eps, factor;
322 PIX *pixt, *pixd;
323 
324  if (!pixs)
325  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
326  if (pixGetDepth(pixs) != 1)
327  return (PIX *)ERROR_PTR("pixs not 1 bpp", __func__, NULL);
328  if (scalefactor <= 0.0)
329  return (PIX *)ERROR_PTR("scalefactor <= 0.0", __func__, NULL);
330  if (scalefactor >= 1.0)
331  return (PIX *)ERROR_PTR("scalefactor >= 1.0", __func__, 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", __func__, 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", __func__, 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", __func__, 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", __func__, 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  if (!pixs)
396  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
397  if (pixGetDepth(pixs) != 1)
398  return (PIX *)ERROR_PTR("pixs must be 1 bpp", __func__, NULL);
399 
400  pixGetDimensions(pixs, &ws, &hs, NULL);
401  wd = ws / 2;
402  hd = hs / 2;
403  if (wd == 0 || hd == 0)
404  return (PIX *)ERROR_PTR("pixs too small", __func__, NULL);
405 
406  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
407  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
408  pixSetPadBits(pixs, 0);
409  pixCopyInputFormat(pixd, pixs);
410  pixCopyResolution(pixd, pixs);
411  pixScaleResolution(pixd, 0.5, 0.5);
412  datas = pixGetData(pixs);
413  datad = pixGetData(pixd);
414  wpls = pixGetWpl(pixs);
415  wpld = pixGetWpl(pixd);
416 
417  sumtab = makeSumTabSG2();
418  valtab = makeValTabSG2();
419  scaleToGray2Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
420  LEPT_FREE(sumtab);
421  LEPT_FREE(valtab);
422  return pixd;
423 }
424 
425 
441 PIX *
443 {
444 l_uint8 *valtab;
445 l_int32 ws, hs, wd, hd;
446 l_int32 wpld, wpls;
447 l_uint32 *sumtab;
448 l_uint32 *datas, *datad;
449 PIX *pixd;
450 
451  if (!pixs)
452  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
453  if (pixGetDepth(pixs) != 1)
454  return (PIX *)ERROR_PTR("pixs not 1 bpp", __func__, NULL);
455 
456  pixGetDimensions(pixs, &ws, &hs, NULL);
457  wd = (ws / 3) & 0xfffffff8; /* truncate to factor of 8 */
458  hd = hs / 3;
459  if (wd == 0 || hd == 0)
460  return (PIX *)ERROR_PTR("pixs too small", __func__, NULL);
461 
462  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
463  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
464  pixCopyInputFormat(pixd, pixs);
465  pixCopyResolution(pixd, pixs);
466  pixScaleResolution(pixd, 0.33333, 0.33333);
467  datas = pixGetData(pixs);
468  datad = pixGetData(pixd);
469  wpls = pixGetWpl(pixs);
470  wpld = pixGetWpl(pixd);
471 
472  sumtab = makeSumTabSG3();
473  valtab = makeValTabSG3();
474  scaleToGray3Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
475  LEPT_FREE(sumtab);
476  LEPT_FREE(valtab);
477  return pixd;
478 }
479 
480 
493 PIX *
495 {
496 l_uint8 *valtab;
497 l_int32 ws, hs, wd, hd;
498 l_int32 wpld, wpls;
499 l_uint32 *sumtab;
500 l_uint32 *datas, *datad;
501 PIX *pixd;
502 
503  if (!pixs)
504  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
505  if (pixGetDepth(pixs) != 1)
506  return (PIX *)ERROR_PTR("pixs must be 1 bpp", __func__, NULL);
507 
508  pixGetDimensions(pixs, &ws, &hs, NULL);
509  wd = (ws / 4) & 0xfffffffe; /* truncate to factor of 2 */
510  hd = hs / 4;
511  if (wd == 0 || hd == 0)
512  return (PIX *)ERROR_PTR("pixs too small", __func__, NULL);
513 
514  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
515  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
516  pixCopyInputFormat(pixd, pixs);
517  pixCopyResolution(pixd, pixs);
518  pixScaleResolution(pixd, 0.25, 0.25);
519  datas = pixGetData(pixs);
520  datad = pixGetData(pixd);
521  wpls = pixGetWpl(pixs);
522  wpld = pixGetWpl(pixd);
523 
524  sumtab = makeSumTabSG4();
525  valtab = makeValTabSG4();
526  scaleToGray4Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
527  LEPT_FREE(sumtab);
528  LEPT_FREE(valtab);
529  return pixd;
530 }
531 
532 
533 
546 PIX *
548 {
549 l_uint8 *valtab;
550 l_int32 ws, hs, wd, hd, wpld, wpls;
551 l_int32 *tab8;
552 l_uint32 *datas, *datad;
553 PIX *pixd;
554 
555  if (!pixs)
556  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
557  if (pixGetDepth(pixs) != 1)
558  return (PIX *)ERROR_PTR("pixs not 1 bpp", __func__, NULL);
559 
560  pixGetDimensions(pixs, &ws, &hs, NULL);
561  wd = (ws / 6) & 0xfffffff8; /* truncate to factor of 8 */
562  hd = hs / 6;
563  if (wd == 0 || hd == 0)
564  return (PIX *)ERROR_PTR("pixs too small", __func__, NULL);
565 
566  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
567  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
568  pixCopyInputFormat(pixd, pixs);
569  pixCopyResolution(pixd, pixs);
570  pixScaleResolution(pixd, 0.16667, 0.16667);
571  datas = pixGetData(pixs);
572  datad = pixGetData(pixd);
573  wpls = pixGetWpl(pixs);
574  wpld = pixGetWpl(pixd);
575 
576  tab8 = makePixelSumTab8();
577  valtab = makeValTabSG6();
578  scaleToGray6Low(datad, wd, hd, wpld, datas, wpls, tab8, valtab);
579  LEPT_FREE(tab8);
580  LEPT_FREE(valtab);
581  return pixd;
582 }
583 
584 
592 PIX *
594 {
595 l_uint8 *valtab;
596 l_int32 ws, hs, wd, hd;
597 l_int32 wpld, wpls;
598 l_int32 *tab8;
599 l_uint32 *datas, *datad;
600 PIX *pixd;
601 
602  if (!pixs)
603  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
604  if (pixGetDepth(pixs) != 1)
605  return (PIX *)ERROR_PTR("pixs must be 1 bpp", __func__, NULL);
606 
607  pixGetDimensions(pixs, &ws, &hs, NULL);
608  wd = ws / 8; /* truncate to nearest dest byte */
609  hd = hs / 8;
610  if (wd == 0 || hd == 0)
611  return (PIX *)ERROR_PTR("pixs too small", __func__, NULL);
612 
613  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
614  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
615  pixCopyInputFormat(pixd, pixs);
616  pixCopyResolution(pixd, pixs);
617  pixScaleResolution(pixd, 0.125, 0.125);
618  datas = pixGetData(pixs);
619  datad = pixGetData(pixd);
620  wpls = pixGetWpl(pixs);
621  wpld = pixGetWpl(pixd);
622 
623  tab8 = makePixelSumTab8();
624  valtab = makeValTabSG8();
625  scaleToGray8Low(datad, wd, hd, wpld, datas, wpls, tab8, valtab);
626  LEPT_FREE(tab8);
627  LEPT_FREE(valtab);
628  return pixd;
629 }
630 
631 
639 PIX *
641 {
642 l_int32 ws, hs, wd, hd;
643 l_int32 wpld, wpls;
644 l_int32 *tab8;
645 l_uint32 *datas, *datad;
646 PIX *pixd;
647 
648  if (!pixs)
649  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
650  if (pixGetDepth(pixs) != 1)
651  return (PIX *)ERROR_PTR("pixs must be 1 bpp", __func__, NULL);
652 
653  pixGetDimensions(pixs, &ws, &hs, NULL);
654  wd = ws / 16;
655  hd = hs / 16;
656  if (wd == 0 || hd == 0)
657  return (PIX *)ERROR_PTR("pixs too small", __func__, NULL);
658 
659  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
660  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
661  pixCopyInputFormat(pixd, pixs);
662  pixCopyResolution(pixd, pixs);
663  pixScaleResolution(pixd, 0.0625, 0.0625);
664  datas = pixGetData(pixs);
665  datad = pixGetData(pixd);
666  wpls = pixGetWpl(pixs);
667  wpld = pixGetWpl(pixd);
668 
669  tab8 = makePixelSumTab8();
670  scaleToGray16Low(datad, wd, hd, wpld, datas, wpls, tab8);
671  LEPT_FREE(tab8);
672  return pixd;
673 }
674 
675 
676 /*------------------------------------------------------------------*
677  * Scale-to-gray mipmap(1 bpp --> 8 bpp, arbitrary reduction) *
678  *------------------------------------------------------------------*/
710 PIX *
712  l_float32 scalefactor)
713 {
714 l_int32 w, h, minsrc, mindest;
715 l_float32 red;
716 PIX *pixs1, *pixs2, *pixt, *pixd;
717 
718  if (!pixs)
719  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
720  if (pixGetDepth(pixs) != 1)
721  return (PIX *)ERROR_PTR("pixs not 1 bpp", __func__, NULL);
722  if (scalefactor <= 0.0)
723  return (PIX *)ERROR_PTR("scalefactor <= 0.0", __func__, NULL);
724  if (scalefactor >= 1.0)
725  return (PIX *)ERROR_PTR("scalefactor >= 1.0", __func__, NULL);
726  pixGetDimensions(pixs, &w, &h, NULL);
727  minsrc = L_MIN(w, h);
728  mindest = (l_int32)((l_float32)minsrc * scalefactor);
729  if (mindest < 2)
730  return (PIX *)ERROR_PTR("scalefactor too small", __func__, NULL);
731 
732  if (scalefactor > 0.5) {
733  pixs1 = pixConvert1To8(NULL, pixs, 255, 0);
734  pixs2 = pixScaleToGray2(pixs);
735  red = scalefactor;
736  } else if (scalefactor == 0.5) {
737  return pixScaleToGray2(pixs);
738  } else if (scalefactor > 0.25) {
739  pixs1 = pixScaleToGray2(pixs);
740  pixs2 = pixScaleToGray4(pixs);
741  red = 2. * scalefactor;
742  } else if (scalefactor == 0.25) {
743  return pixScaleToGray4(pixs);
744  } else if (scalefactor > 0.125) {
745  pixs1 = pixScaleToGray4(pixs);
746  pixs2 = pixScaleToGray8(pixs);
747  red = 4. * scalefactor;
748  } else if (scalefactor == 0.125) {
749  return pixScaleToGray8(pixs);
750  } else if (scalefactor > 0.0625) {
751  pixs1 = pixScaleToGray8(pixs);
752  pixs2 = pixScaleToGray16(pixs);
753  red = 8. * scalefactor;
754  } else if (scalefactor == 0.0625) {
755  return pixScaleToGray16(pixs);
756  } else { /* end of the pyramid; just do it */
757  red = 16.0 * scalefactor; /* will be <= 1.0 */
758  if ((pixt = pixScaleToGray16(pixs)) == NULL)
759  return (PIX *)ERROR_PTR("pixt not made", __func__, NULL);
760  if (red < 0.7)
761  pixd = pixScaleSmooth(pixt, red, red);
762  else
763  pixd = pixScaleGrayLI(pixt, red, red);
764  pixDestroy(&pixt);
765  return pixd;
766  }
767 
768  pixd = pixScaleMipmap(pixs1, pixs2, red);
769  pixCopyInputFormat(pixd, pixs);
770 
771  pixDestroy(&pixs1);
772  pixDestroy(&pixs2);
773  return pixd;
774 }
775 
776 
777 /*------------------------------------------------------------------*
778  * Grayscale scaling using mipmap *
779  *------------------------------------------------------------------*/
796 PIX *
798  PIX *pixs2,
799  l_float32 scale)
800 {
801 l_int32 ws1, hs1, ws2, hs2, wd, hd, wpls1, wpls2, wpld;
802 l_uint32 *datas1, *datas2, *datad;
803 PIX *pixd;
804 
805  if (!pixs1 || pixGetDepth(pixs1) != 8 || pixGetColormap(pixs1))
806  return (PIX *)ERROR_PTR("pixs1 underdefined, not 8 bpp, or cmapped",
807  __func__, NULL);
808  if (!pixs2 || pixGetDepth(pixs2) != 8 || pixGetColormap(pixs2))
809  return (PIX *)ERROR_PTR("pixs2 underdefined, not 8 bpp, or cmapped",
810  __func__, NULL);
811  pixGetDimensions(pixs1, &ws1, &hs1, NULL);
812  pixGetDimensions(pixs2, &ws2, &hs2, NULL);
813  if (scale > 1.0 || scale < 0.5)
814  return (PIX *)ERROR_PTR("scale not in [0.5, 1.0]", __func__, NULL);
815  if (ws1 < 2 * ws2)
816  return (PIX *)ERROR_PTR("invalid width ratio", __func__, NULL);
817  if (hs1 < 2 * hs2)
818  return (PIX *)ERROR_PTR("invalid height ratio", __func__, NULL);
819 
820  /* Generate wd and hd from the lower resolution dimensions,
821  * to guarantee staying within both src images */
822  datas1 = pixGetData(pixs1);
823  wpls1 = pixGetWpl(pixs1);
824  datas2 = pixGetData(pixs2);
825  wpls2 = pixGetWpl(pixs2);
826  wd = (l_int32)(2. * scale * pixGetWidth(pixs2));
827  hd = (l_int32)(2. * scale * pixGetHeight(pixs2));
828  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
829  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
830  pixCopyInputFormat(pixd, pixs1);
831  pixCopyResolution(pixd, pixs1);
832  pixScaleResolution(pixd, scale, scale);
833  datad = pixGetData(pixd);
834  wpld = pixGetWpl(pixd);
835 
836  scaleMipmapLow(datad, wd, hd, wpld, datas1, wpls1, datas2, wpls2, scale);
837  return pixd;
838 }
839 
840 
841 /*------------------------------------------------------------------*
842  * Replicated (integer) expansion *
843  *------------------------------------------------------------------*/
851 PIX *
853  l_int32 factor)
854 {
855 l_int32 w, h, d, wd, hd, wpls, wpld, start, i, j, k;
856 l_uint8 sval;
857 l_uint16 sval16;
858 l_uint32 sval32;
859 l_uint32 *lines, *datas, *lined, *datad;
860 PIX *pixd;
861 
862  if (!pixs)
863  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
864  pixGetDimensions(pixs, &w, &h, &d);
865  if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
866  return (PIX *)ERROR_PTR("depth not in {1,2,4,8,16,32}", __func__, NULL);
867  if (factor <= 0)
868  return (PIX *)ERROR_PTR("factor <= 0; invalid", __func__, NULL);
869  if (factor == 1)
870  return pixCopy(NULL, pixs);
871 
872  if (d == 1)
873  return pixExpandBinaryReplicate(pixs, factor, factor);
874 
875  wd = factor * w;
876  hd = factor * h;
877  if ((pixd = pixCreate(wd, hd, d)) == NULL)
878  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
879  pixCopyColormap(pixd, pixs);
880  pixCopyInputFormat(pixd, pixs);
881  pixCopyResolution(pixd, pixs);
882  pixScaleResolution(pixd, (l_float32)factor, (l_float32)factor);
883  datas = pixGetData(pixs);
884  wpls = pixGetWpl(pixs);
885  datad = pixGetData(pixd);
886  wpld = pixGetWpl(pixd);
887 
888  switch (d) {
889  case 2:
890  for (i = 0; i < h; i++) {
891  lines = datas + i * wpls;
892  lined = datad + factor * i * wpld;
893  for (j = 0; j < w; j++) {
894  sval = GET_DATA_DIBIT(lines, j);
895  start = factor * j;
896  for (k = 0; k < factor; k++)
897  SET_DATA_DIBIT(lined, start + k, sval);
898  }
899  for (k = 1; k < factor; k++)
900  memcpy(lined + k * wpld, lined, 4 * wpld);
901  }
902  break;
903  case 4:
904  for (i = 0; i < h; i++) {
905  lines = datas + i * wpls;
906  lined = datad + factor * i * wpld;
907  for (j = 0; j < w; j++) {
908  sval = GET_DATA_QBIT(lines, j);
909  start = factor * j;
910  for (k = 0; k < factor; k++)
911  SET_DATA_QBIT(lined, start + k, sval);
912  }
913  for (k = 1; k < factor; k++)
914  memcpy(lined + k * wpld, lined, 4 * wpld);
915  }
916  break;
917  case 8:
918  for (i = 0; i < h; i++) {
919  lines = datas + i * wpls;
920  lined = datad + factor * i * wpld;
921  for (j = 0; j < w; j++) {
922  sval = GET_DATA_BYTE(lines, j);
923  start = factor * j;
924  for (k = 0; k < factor; k++)
925  SET_DATA_BYTE(lined, start + k, sval);
926  }
927  for (k = 1; k < factor; k++)
928  memcpy(lined + k * wpld, lined, 4 * wpld);
929  }
930  break;
931  case 16:
932  for (i = 0; i < h; i++) {
933  lines = datas + i * wpls;
934  lined = datad + factor * i * wpld;
935  for (j = 0; j < w; j++) {
936  sval16 = GET_DATA_TWO_BYTES(lines, j);
937  start = factor * j;
938  for (k = 0; k < factor; k++)
939  SET_DATA_TWO_BYTES(lined, start + k, sval16);
940  }
941  for (k = 1; k < factor; k++)
942  memcpy(lined + k * wpld, lined, 4 * wpld);
943  }
944  break;
945  case 32:
946  for (i = 0; i < h; i++) {
947  lines = datas + i * wpls;
948  lined = datad + factor * i * wpld;
949  for (j = 0; j < w; j++) {
950  sval32 = *(lines + j);
951  start = factor * j;
952  for (k = 0; k < factor; k++)
953  *(lined + start + k) = sval32;
954  }
955  for (k = 1; k < factor; k++)
956  memcpy(lined + k * wpld, lined, 4 * wpld);
957  }
958  break;
959  default:
960  lept_stderr("invalid depth\n");
961  }
962 
963  if (d == 32 && pixGetSpp(pixs) == 4)
964  pixScaleAndTransferAlpha(pixd, pixs, (l_float32)factor,
965  (l_float32)factor);
966  return pixd;
967 }
968 
969 
970 /*-----------------------------------------------------------------------*
971  * Downscaling using min or max *
972  *-----------------------------------------------------------------------*/
996 PIX *
998  l_int32 xfact,
999  l_int32 yfact,
1000  l_int32 type)
1001 {
1002 l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k, m;
1003 l_int32 minval, maxval, val;
1004 l_uint32 *datas, *datad, *lines, *lined;
1005 PIX *pixd;
1006 
1007  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1008  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1009  __func__, NULL);
1010  pixGetDimensions(pixs, &ws, &hs, NULL);
1011  if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX &&
1012  type != L_CHOOSE_MAXDIFF)
1013  return (PIX *)ERROR_PTR("invalid type", __func__, NULL);
1014  if (xfact < 1 || yfact < 1)
1015  return (PIX *)ERROR_PTR("xfact and yfact must be >= 1", __func__, NULL);
1016 
1017  if (xfact == 2 && yfact == 2)
1018  return pixScaleGrayMinMax2(pixs, type);
1019 
1020  wd = ws / xfact;
1021  if (wd == 0) { /* single tile */
1022  wd = 1;
1023  xfact = ws;
1024  }
1025  hd = hs / yfact;
1026  if (hd == 0) { /* single tile */
1027  hd = 1;
1028  yfact = hs;
1029  }
1030  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1031  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
1032  pixCopyInputFormat(pixd, pixs);
1033  datas = pixGetData(pixs);
1034  datad = pixGetData(pixd);
1035  wpls = pixGetWpl(pixs);
1036  wpld = pixGetWpl(pixd);
1037  for (i = 0; i < hd; i++) {
1038  lined = datad + i * wpld;
1039  for (j = 0; j < wd; j++) {
1040  if (type == L_CHOOSE_MIN || type == L_CHOOSE_MAXDIFF) {
1041  minval = 255;
1042  for (k = 0; k < yfact; k++) {
1043  lines = datas + (yfact * i + k) * wpls;
1044  for (m = 0; m < xfact; m++) {
1045  val = GET_DATA_BYTE(lines, xfact * j + m);
1046  if (val < minval)
1047  minval = val;
1048  }
1049  }
1050  }
1051  if (type == L_CHOOSE_MAX || type == L_CHOOSE_MAXDIFF) {
1052  maxval = 0;
1053  for (k = 0; k < yfact; k++) {
1054  lines = datas + (yfact * i + k) * wpls;
1055  for (m = 0; m < xfact; m++) {
1056  val = GET_DATA_BYTE(lines, xfact * j + m);
1057  if (val > maxval)
1058  maxval = val;
1059  }
1060  }
1061  }
1062  if (type == L_CHOOSE_MIN)
1063  SET_DATA_BYTE(lined, j, minval);
1064  else if (type == L_CHOOSE_MAX)
1065  SET_DATA_BYTE(lined, j, maxval);
1066  else /* type == L_CHOOSE_MAXDIFF */
1067  SET_DATA_BYTE(lined, j, maxval - minval);
1068  }
1069  }
1070 
1071  return pixd;
1072 }
1073 
1074 
1101 PIX *
1103  l_int32 type)
1104 {
1105 l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k;
1106 l_int32 minval, maxval;
1107 l_int32 val[4];
1108 l_uint32 *datas, *datad, *lines, *lined;
1109 PIX *pixd;
1110 
1111  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1112  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1113  __func__, NULL);
1114  pixGetDimensions(pixs, &ws, &hs, NULL);
1115  if (ws < 2 || hs < 2)
1116  return (PIX *)ERROR_PTR("too small: ws < 2 or hs < 2", __func__, NULL);
1117  if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX &&
1118  type != L_CHOOSE_MAXDIFF)
1119  return (PIX *)ERROR_PTR("invalid type", __func__, NULL);
1120 
1121  wd = ws / 2;
1122  hd = hs / 2;
1123  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1124  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
1125  pixCopyInputFormat(pixd, pixs);
1126  datas = pixGetData(pixs);
1127  datad = pixGetData(pixd);
1128  wpls = pixGetWpl(pixs);
1129  wpld = pixGetWpl(pixd);
1130  for (i = 0; i < hd; i++) {
1131  lines = datas + 2 * i * wpls;
1132  lined = datad + i * wpld;
1133  for (j = 0; j < wd; j++) {
1134  val[0] = GET_DATA_BYTE(lines, 2 * j);
1135  val[1] = GET_DATA_BYTE(lines, 2 * j + 1);
1136  val[2] = GET_DATA_BYTE(lines + wpls, 2 * j);
1137  val[3] = GET_DATA_BYTE(lines + wpls, 2 * j + 1);
1138  if (type == L_CHOOSE_MIN || type == L_CHOOSE_MAXDIFF) {
1139  minval = 255;
1140  for (k = 0; k < 4; k++) {
1141  if (val[k] < minval)
1142  minval = val[k];
1143  }
1144  }
1145  if (type == L_CHOOSE_MAX || type == L_CHOOSE_MAXDIFF) {
1146  maxval = 0;
1147  for (k = 0; k < 4; k++) {
1148  if (val[k] > maxval)
1149  maxval = val[k];
1150  }
1151  }
1152  if (type == L_CHOOSE_MIN)
1153  SET_DATA_BYTE(lined, j, minval);
1154  else if (type == L_CHOOSE_MAX)
1155  SET_DATA_BYTE(lined, j, maxval);
1156  else /* type == L_CHOOSE_MAXDIFF */
1157  SET_DATA_BYTE(lined, j, maxval - minval);
1158  }
1159  }
1160 
1161  return pixd;
1162 }
1163 
1164 
1165 /*-----------------------------------------------------------------------*
1166  * Grayscale downscaling using rank value *
1167  *-----------------------------------------------------------------------*/
1182 PIX *
1184  l_int32 level1,
1185  l_int32 level2,
1186  l_int32 level3,
1187  l_int32 level4)
1188 {
1189 PIX *pixt1, *pixt2, *pixt3, *pixt4;
1190 
1191  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1192  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1193  __func__, NULL);
1194  if (level1 > 4 || level2 > 4 || level3 > 4 || level4 > 4)
1195  return (PIX *)ERROR_PTR("levels must not exceed 4", __func__, NULL);
1196 
1197  if (level1 <= 0) {
1198  L_WARNING("no reduction because level1 not > 0\n", __func__);
1199  return pixCopy(NULL, pixs);
1200  }
1201 
1202  pixt1 = pixScaleGrayRank2(pixs, level1);
1203  if (level2 <= 0)
1204  return pixt1;
1205 
1206  pixt2 = pixScaleGrayRank2(pixt1, level2);
1207  pixDestroy(&pixt1);
1208  if (level3 <= 0)
1209  return pixt2;
1210 
1211  pixt3 = pixScaleGrayRank2(pixt2, level3);
1212  pixDestroy(&pixt2);
1213  if (level4 <= 0)
1214  return pixt3;
1215 
1216  pixt4 = pixScaleGrayRank2(pixt3, level4);
1217  pixDestroy(&pixt3);
1218  return pixt4;
1219 }
1220 
1221 
1244 PIX *
1246  l_int32 rank)
1247 {
1248 l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k, m;
1249 l_int32 minval, maxval, rankval, minindex, maxindex;
1250 l_int32 val[4];
1251 l_int32 midval[4]; /* should only use 2 of these */
1252 l_uint32 *datas, *datad, *lines, *lined;
1253 PIX *pixd;
1254 
1255  if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1256  return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1257  __func__, NULL);
1258  if (rank < 1 || rank > 4)
1259  return (PIX *)ERROR_PTR("invalid rank", __func__, NULL);
1260 
1261  if (rank == 1)
1262  return pixScaleGrayMinMax2(pixs, L_CHOOSE_MIN);
1263  if (rank == 4)
1264  return pixScaleGrayMinMax2(pixs, L_CHOOSE_MAX);
1265 
1266  pixGetDimensions(pixs, &ws, &hs, NULL);
1267  wd = ws / 2;
1268  hd = hs / 2;
1269  if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1270  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
1271  pixCopyInputFormat(pixd, pixs);
1272  datas = pixGetData(pixs);
1273  datad = pixGetData(pixd);
1274  wpls = pixGetWpl(pixs);
1275  wpld = pixGetWpl(pixd);
1276  for (i = 0; i < hd; i++) {
1277  lines = datas + 2 * i * wpls;
1278  lined = datad + i * wpld;
1279  for (j = 0; j < wd; j++) {
1280  val[0] = GET_DATA_BYTE(lines, 2 * j);
1281  val[1] = GET_DATA_BYTE(lines, 2 * j + 1);
1282  val[2] = GET_DATA_BYTE(lines + wpls, 2 * j);
1283  val[3] = GET_DATA_BYTE(lines + wpls, 2 * j + 1);
1284  minval = maxval = val[0];
1285  minindex = maxindex = 0;
1286  for (k = 1; k < 4; k++) {
1287  if (val[k] < minval) {
1288  minval = val[k];
1289  minindex = k;
1290  continue;
1291  }
1292  if (val[k] > maxval) {
1293  maxval = val[k];
1294  maxindex = k;
1295  }
1296  }
1297  for (k = 0, m = 0; k < 4; k++) {
1298  if (k == minindex || k == maxindex)
1299  continue;
1300  midval[m++] = val[k];
1301  }
1302  if (m > 2) /* minval == maxval; all val[k] are the same */
1303  rankval = minval;
1304  else if (rank == 2)
1305  rankval = L_MIN(midval[0], midval[1]);
1306  else /* rank == 3 */
1307  rankval = L_MAX(midval[0], midval[1]);
1308  SET_DATA_BYTE(lined, j, rankval);
1309  }
1310  }
1311 
1312  return pixd;
1313 }
1314 
1315 
1316 /*------------------------------------------------------------------------*
1317  * Helper function for transferring alpha with scaling *
1318  *------------------------------------------------------------------------*/
1333 l_ok
1335  PIX *pixs,
1336  l_float32 scalex,
1337  l_float32 scaley)
1338 {
1339 PIX *pix1, *pix2;
1340 
1341  if (!pixs || !pixd)
1342  return ERROR_INT("pixs and pixd not both defined", __func__, 1);
1343  if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
1344  return ERROR_INT("pixs not 32 bpp and 4 spp", __func__, 1);
1345  if (pixGetDepth(pixd) != 32)
1346  return ERROR_INT("pixd not 32 bpp", __func__, 1);
1347 
1348  if (scalex == 1.0 && scaley == 1.0) {
1349  pixCopyRGBComponent(pixd, pixs, L_ALPHA_CHANNEL);
1350  return 0;
1351  }
1352 
1353  pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
1354  pix2 = pixScale(pix1, scalex, scaley);
1355  pixSetRGBComponent(pixd, pix2, L_ALPHA_CHANNEL);
1356  pixDestroy(&pix1);
1357  pixDestroy(&pix2);
1358  return 0;
1359 }
1360 
1361 
1362 /*------------------------------------------------------------------------*
1363  * RGB scaling including alpha (blend) component and gamma transform *
1364  *------------------------------------------------------------------------*/
1410 PIX *
1412  l_float32 scalex,
1413  l_float32 scaley,
1414  PIX *pixg,
1415  l_float32 fract)
1416 {
1417 l_int32 ws, hs, d, spp;
1418 PIX *pixd, *pix32, *pixg2, *pixgs;
1419 
1420  if (!pixs)
1421  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1422  pixGetDimensions(pixs, &ws, &hs, &d);
1423  if (d != 32 && !pixGetColormap(pixs))
1424  return (PIX *)ERROR_PTR("pixs not cmapped or 32 bpp", __func__, NULL);
1425  if (scalex <= 0.0 || scaley <= 0.0)
1426  return (PIX *)ERROR_PTR("scale factor <= 0.0", __func__, NULL);
1427  if (pixg && pixGetDepth(pixg) != 8) {
1428  L_WARNING("pixg not 8 bpp; using 'fract' transparent alpha\n",
1429  __func__);
1430  pixg = NULL;
1431  }
1432  if (!pixg && (fract < 0.0 || fract > 1.0)) {
1433  L_WARNING("invalid fract; using fully opaque\n", __func__);
1434  fract = 1.0;
1435  }
1436  if (!pixg && fract == 0.0)
1437  L_WARNING("transparent alpha; image will not be blended\n", __func__);
1438 
1439  /* Make sure input to scaling is 32 bpp rgb, and scale it */
1440  if (d != 32)
1441  pix32 = pixConvertTo32(pixs);
1442  else
1443  pix32 = pixClone(pixs);
1444  spp = pixGetSpp(pix32);
1445  pixSetSpp(pix32, 3); /* ignore the alpha channel for scaling */
1446  pixd = pixScale(pix32, scalex, scaley);
1447  pixSetSpp(pix32, spp); /* restore initial value in case it's a clone */
1448  pixDestroy(&pix32);
1449 
1450  /* Set up alpha layer with a fading border and scale it */
1451  if (!pixg) {
1452  pixg2 = pixCreate(ws, hs, 8);
1453  if (fract == 1.0)
1454  pixSetAll(pixg2);
1455  else if (fract > 0.0)
1456  pixSetAllArbitrary(pixg2, (l_int32)(255.0 * fract));
1457  } else {
1458  pixg2 = pixResizeToMatch(pixg, NULL, ws, hs);
1459  }
1460  if (ws > 10 && hs > 10) { /* see note 4 */
1461  pixSetBorderRingVal(pixg2, 1,
1462  (l_int32)(255.0 * fract * AlphaMaskBorderVals[0]));
1463  pixSetBorderRingVal(pixg2, 2,
1464  (l_int32)(255.0 * fract * AlphaMaskBorderVals[1]));
1465  }
1466  pixgs = pixScaleGeneral(pixg2, scalex, scaley, 0.0, 0);
1467 
1468  /* Combine into a 4 spp result */
1469  pixSetRGBComponent(pixd, pixgs, L_ALPHA_CHANNEL);
1470  pixCopyInputFormat(pixd, pixs);
1471 
1472  pixDestroy(&pixg2);
1473  pixDestroy(&pixgs);
1474  return pixd;
1475 }
1476 
1477 
1478 /* ================================================================ *
1479  * Low level static functions *
1480  * ================================================================ */
1481 
1482 /*------------------------------------------------------------------*
1483  * Scale-to-gray 2x *
1484  *------------------------------------------------------------------*/
1510 static void
1511 scaleToGray2Low(l_uint32 *datad,
1512  l_int32 wd,
1513  l_int32 hd,
1514  l_int32 wpld,
1515  l_uint32 *datas,
1516  l_int32 wpls,
1517  l_uint32 *sumtab,
1518  l_uint8 *valtab)
1519 {
1520 l_int32 i, j, l, k, m, wd4, extra;
1521 l_uint32 sbyte1, sbyte2, sum;
1522 l_uint32 *lines, *lined;
1523 
1524  /* i indexes the dest lines
1525  * l indexes the source lines
1526  * j indexes the dest bytes
1527  * k indexes the source bytes
1528  * We take two bytes from the source (in 2 lines of 8 pixels
1529  * each) and convert them into four 8 bpp bytes of the dest. */
1530  wd4 = wd & 0xfffffffc;
1531  extra = wd - wd4;
1532  for (i = 0, l = 0; i < hd; i++, l += 2) {
1533  lines = datas + l * wpls;
1534  lined = datad + i * wpld;
1535  for (j = 0, k = 0; j < wd4; j += 4, k++) {
1536  sbyte1 = GET_DATA_BYTE(lines, k);
1537  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1538  sum = sumtab[sbyte1] + sumtab[sbyte2];
1539  SET_DATA_BYTE(lined, j, valtab[sum >> 24]);
1540  SET_DATA_BYTE(lined, j + 1, valtab[(sum >> 16) & 0xff]);
1541  SET_DATA_BYTE(lined, j + 2, valtab[(sum >> 8) & 0xff]);
1542  SET_DATA_BYTE(lined, j + 3, valtab[sum & 0xff]);
1543  }
1544  if (extra > 0) {
1545  sbyte1 = GET_DATA_BYTE(lines, k);
1546  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1547  sum = sumtab[sbyte1] + sumtab[sbyte2];
1548  for (m = 0; m < extra; m++) {
1549  SET_DATA_BYTE(lined, j + m,
1550  valtab[((sum >> (24 - 8 * m)) & 0xff)]);
1551  }
1552  }
1553 
1554  }
1555 }
1556 
1557 
1570 static l_uint32 *
1572 {
1573 l_int32 i;
1574 l_int32 sum[] = {0, 1, 1, 2};
1575 l_uint32 *tab;
1576 
1577  /* Pack the four sums separately in four bytes */
1578  tab = (l_uint32 *)LEPT_CALLOC(256, sizeof(l_uint32));
1579  for (i = 0; i < 256; i++) {
1580  tab[i] = (sum[i & 0x3] | sum[(i >> 2) & 0x3] << 8 |
1581  sum[(i >> 4) & 0x3] << 16 | sum[(i >> 6) & 0x3] << 24);
1582  }
1583  return tab;
1584 }
1585 
1586 
1598 static l_uint8 *
1600 {
1601 l_int32 i;
1602 l_uint8 *tab;
1603 
1604  tab = (l_uint8 *)LEPT_CALLOC(5, sizeof(l_uint8));
1605  for (i = 0; i < 5; i++)
1606  tab[i] = 255 - (i * 255) / 4;
1607  return tab;
1608 }
1609 
1610 
1611 /*------------------------------------------------------------------*
1612  * Scale-to-gray 3x *
1613  *------------------------------------------------------------------*/
1648 static void
1649 scaleToGray3Low(l_uint32 *datad,
1650  l_int32 wd,
1651  l_int32 hd,
1652  l_int32 wpld,
1653  l_uint32 *datas,
1654  l_int32 wpls,
1655  l_uint32 *sumtab,
1656  l_uint8 *valtab)
1657 {
1658 l_int32 i, j, l, k;
1659 l_uint32 threebytes1, threebytes2, threebytes3, sum;
1660 l_uint32 *lines, *lined;
1661 
1662  /* i indexes the dest lines
1663  * l indexes the source lines
1664  * j indexes the dest bytes
1665  * k indexes the source bytes
1666  * We take 9 bytes from the source (72 binary pixels
1667  * in three lines of 24 pixels each) and convert it
1668  * into 8 bytes of the dest (8 8bpp pixels in one line) */
1669  for (i = 0, l = 0; i < hd; i++, l += 3) {
1670  lines = datas + l * wpls;
1671  lined = datad + i * wpld;
1672  for (j = 0, k = 0; j < wd; j += 8, k += 3) {
1673  threebytes1 = (GET_DATA_BYTE(lines, k) << 16) |
1674  (GET_DATA_BYTE(lines, k + 1) << 8) |
1675  GET_DATA_BYTE(lines, k + 2);
1676  threebytes2 = (GET_DATA_BYTE(lines + wpls, k) << 16) |
1677  (GET_DATA_BYTE(lines + wpls, k + 1) << 8) |
1678  GET_DATA_BYTE(lines + wpls, k + 2);
1679  threebytes3 = (GET_DATA_BYTE(lines + 2 * wpls, k) << 16) |
1680  (GET_DATA_BYTE(lines + 2 * wpls, k + 1) << 8) |
1681  GET_DATA_BYTE(lines + 2 * wpls, k + 2);
1682 
1683  sum = sumtab[(threebytes1 >> 18)] +
1684  sumtab[(threebytes2 >> 18)] +
1685  sumtab[(threebytes3 >> 18)];
1686  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 2)]);
1687  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1688 
1689  sum = sumtab[((threebytes1 >> 12) & 0x3f)] +
1690  sumtab[((threebytes2 >> 12) & 0x3f)] +
1691  sumtab[((threebytes3 >> 12) & 0x3f)];
1692  SET_DATA_BYTE(lined, j + 2, valtab[GET_DATA_BYTE(&sum, 2)]);
1693  SET_DATA_BYTE(lined, j + 3, valtab[GET_DATA_BYTE(&sum, 3)]);
1694 
1695  sum = sumtab[((threebytes1 >> 6) & 0x3f)] +
1696  sumtab[((threebytes2 >> 6) & 0x3f)] +
1697  sumtab[((threebytes3 >> 6) & 0x3f)];
1698  SET_DATA_BYTE(lined, j + 4, valtab[GET_DATA_BYTE(&sum, 2)]);
1699  SET_DATA_BYTE(lined, j + 5, valtab[GET_DATA_BYTE(&sum, 3)]);
1700 
1701  sum = sumtab[(threebytes1 & 0x3f)] +
1702  sumtab[(threebytes2 & 0x3f)] +
1703  sumtab[(threebytes3 & 0x3f)];
1704  SET_DATA_BYTE(lined, j + 6, valtab[GET_DATA_BYTE(&sum, 2)]);
1705  SET_DATA_BYTE(lined, j + 7, valtab[GET_DATA_BYTE(&sum, 3)]);
1706  }
1707  }
1708 }
1709 
1710 
1711 
1725 static l_uint32 *
1727 {
1728 l_int32 i;
1729 l_int32 sum[] = {0, 1, 1, 2, 1, 2, 2, 3};
1730 l_uint32 *tab;
1731 
1732  /* Pack the two sums separately in two bytes */
1733  tab = (l_uint32 *)LEPT_CALLOC(64, sizeof(l_uint32));
1734  for (i = 0; i < 64; i++) {
1735  tab[i] = (sum[i & 0x07]) | (sum[(i >> 3) & 0x07] << 8);
1736  }
1737  return tab;
1738 }
1739 
1740 
1752 static l_uint8 *
1754 {
1755 l_int32 i;
1756 l_uint8 *tab;
1757 
1758  tab = (l_uint8 *)LEPT_CALLOC(10, sizeof(l_uint8));
1759  for (i = 0; i < 10; i++)
1760  tab[i] = 0xff - (i * 255) / 9;
1761  return tab;
1762 }
1763 
1764 
1765 /*------------------------------------------------------------------*
1766  * Scale-to-gray 4x *
1767  *------------------------------------------------------------------*/
1793 static void
1794 scaleToGray4Low(l_uint32 *datad,
1795  l_int32 wd,
1796  l_int32 hd,
1797  l_int32 wpld,
1798  l_uint32 *datas,
1799  l_int32 wpls,
1800  l_uint32 *sumtab,
1801  l_uint8 *valtab)
1802 {
1803 l_int32 i, j, l, k;
1804 l_uint32 sbyte1, sbyte2, sbyte3, sbyte4, sum;
1805 l_uint32 *lines, *lined;
1806 
1807  /* i indexes the dest lines
1808  * l indexes the source lines
1809  * j indexes the dest bytes
1810  * k indexes the source bytes
1811  * We take four bytes from the source (in 4 lines of 8 pixels
1812  * each) and convert it into two 8 bpp bytes of the dest. */
1813  for (i = 0, l = 0; i < hd; i++, l += 4) {
1814  lines = datas + l * wpls;
1815  lined = datad + i * wpld;
1816  for (j = 0, k = 0; j < wd; j += 2, k++) {
1817  sbyte1 = GET_DATA_BYTE(lines, k);
1818  sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1819  sbyte3 = GET_DATA_BYTE(lines + 2 * wpls, k);
1820  sbyte4 = GET_DATA_BYTE(lines + 3 * wpls, k);
1821  sum = sumtab[sbyte1] + sumtab[sbyte2] +
1822  sumtab[sbyte3] + sumtab[sbyte4];
1823  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 2)]);
1824  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1825  }
1826  }
1827 }
1828 
1829 
1842 static l_uint32 *
1844 {
1845 l_int32 i;
1846 l_int32 sum[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1847 l_uint32 *tab;
1848 
1849  /* Pack the two sums separately in two bytes */
1850  tab = (l_uint32 *)LEPT_CALLOC(256, sizeof(l_uint32));
1851  for (i = 0; i < 256; i++) {
1852  tab[i] = (sum[i & 0xf]) | (sum[(i >> 4) & 0xf] << 8);
1853  }
1854  return tab;
1855 }
1856 
1857 
1869 static l_uint8 *
1871 {
1872 l_int32 i;
1873 l_uint8 *tab;
1874 
1875  tab = (l_uint8 *)LEPT_CALLOC(17, sizeof(l_uint8));
1876  for (i = 0; i < 17; i++)
1877  tab[i] = 0xff - (i * 255) / 16;
1878  return tab;
1879 }
1880 
1881 
1882 /*------------------------------------------------------------------*
1883  * Scale-to-gray 6x *
1884  *------------------------------------------------------------------*/
1918 static void
1919 scaleToGray6Low(l_uint32 *datad,
1920  l_int32 wd,
1921  l_int32 hd,
1922  l_int32 wpld,
1923  l_uint32 *datas,
1924  l_int32 wpls,
1925  l_int32 *tab8,
1926  l_uint8 *valtab)
1927 {
1928 l_int32 i, j, l, k;
1929 l_uint32 threebytes1, threebytes2, threebytes3;
1930 l_uint32 threebytes4, threebytes5, threebytes6, sum;
1931 l_uint32 *lines, *lined;
1932 
1933  /* i indexes the dest lines
1934  * l indexes the source lines
1935  * j indexes the dest bytes
1936  * k indexes the source bytes
1937  * We take 18 bytes from the source (144 binary pixels
1938  * in six lines of 24 pixels each) and convert it
1939  * into 4 bytes of the dest (four 8 bpp pixels in one line) */
1940  for (i = 0, l = 0; i < hd; i++, l += 6) {
1941  lines = datas + l * wpls;
1942  lined = datad + i * wpld;
1943  for (j = 0, k = 0; j < wd; j += 4, k += 3) {
1944  /* First grab the 18 bytes, 3 at a time, and put each set
1945  * of 3 bytes into the LS bytes of a 32-bit word. */
1946  threebytes1 = (GET_DATA_BYTE(lines, k) << 16) |
1947  (GET_DATA_BYTE(lines, k + 1) << 8) |
1948  GET_DATA_BYTE(lines, k + 2);
1949  threebytes2 = (GET_DATA_BYTE(lines + wpls, k) << 16) |
1950  (GET_DATA_BYTE(lines + wpls, k + 1) << 8) |
1951  GET_DATA_BYTE(lines + wpls, k + 2);
1952  threebytes3 = (GET_DATA_BYTE(lines + 2 * wpls, k) << 16) |
1953  (GET_DATA_BYTE(lines + 2 * wpls, k + 1) << 8) |
1954  GET_DATA_BYTE(lines + 2 * wpls, k + 2);
1955  threebytes4 = (GET_DATA_BYTE(lines + 3 * wpls, k) << 16) |
1956  (GET_DATA_BYTE(lines + 3 * wpls, k + 1) << 8) |
1957  GET_DATA_BYTE(lines + 3 * wpls, k + 2);
1958  threebytes5 = (GET_DATA_BYTE(lines + 4 * wpls, k) << 16) |
1959  (GET_DATA_BYTE(lines + 4 * wpls, k + 1) << 8) |
1960  GET_DATA_BYTE(lines + 4 * wpls, k + 2);
1961  threebytes6 = (GET_DATA_BYTE(lines + 5 * wpls, k) << 16) |
1962  (GET_DATA_BYTE(lines + 5 * wpls, k + 1) << 8) |
1963  GET_DATA_BYTE(lines + 5 * wpls, k + 2);
1964 
1965  /* Sum first set of 36 bits and convert to 0-255 */
1966  sum = tab8[(threebytes1 >> 18)] +
1967  tab8[(threebytes2 >> 18)] +
1968  tab8[(threebytes3 >> 18)] +
1969  tab8[(threebytes4 >> 18)] +
1970  tab8[(threebytes5 >> 18)] +
1971  tab8[(threebytes6 >> 18)];
1972  SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 3)]);
1973 
1974  /* Ditto for second set */
1975  sum = tab8[((threebytes1 >> 12) & 0x3f)] +
1976  tab8[((threebytes2 >> 12) & 0x3f)] +
1977  tab8[((threebytes3 >> 12) & 0x3f)] +
1978  tab8[((threebytes4 >> 12) & 0x3f)] +
1979  tab8[((threebytes5 >> 12) & 0x3f)] +
1980  tab8[((threebytes6 >> 12) & 0x3f)];
1981  SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1982 
1983  sum = tab8[((threebytes1 >> 6) & 0x3f)] +
1984  tab8[((threebytes2 >> 6) & 0x3f)] +
1985  tab8[((threebytes3 >> 6) & 0x3f)] +
1986  tab8[((threebytes4 >> 6) & 0x3f)] +
1987  tab8[((threebytes5 >> 6) & 0x3f)] +
1988  tab8[((threebytes6 >> 6) & 0x3f)];
1989  SET_DATA_BYTE(lined, j + 2, valtab[GET_DATA_BYTE(&sum, 3)]);
1990 
1991  sum = tab8[(threebytes1 & 0x3f)] +
1992  tab8[(threebytes2 & 0x3f)] +
1993  tab8[(threebytes3 & 0x3f)] +
1994  tab8[(threebytes4 & 0x3f)] +
1995  tab8[(threebytes5 & 0x3f)] +
1996  tab8[(threebytes6 & 0x3f)];
1997  SET_DATA_BYTE(lined, j + 3, valtab[GET_DATA_BYTE(&sum, 3)]);
1998  }
1999  }
2000 }
2001 
2002 
2014 static l_uint8 *
2016 {
2017 l_int32 i;
2018 l_uint8 *tab;
2019 
2020  tab = (l_uint8 *)LEPT_CALLOC(37, sizeof(l_uint8));
2021  for (i = 0; i < 37; i++)
2022  tab[i] = 0xff - (i * 255) / 36;
2023  return tab;
2024 }
2025 
2026 
2027 /*------------------------------------------------------------------*
2028  * Scale-to-gray 8x *
2029  *------------------------------------------------------------------*/
2054 static void
2055 scaleToGray8Low(l_uint32 *datad,
2056  l_int32 wd,
2057  l_int32 hd,
2058  l_int32 wpld,
2059  l_uint32 *datas,
2060  l_int32 wpls,
2061  l_int32 *tab8,
2062  l_uint8 *valtab)
2063 {
2064 l_int32 i, j, k;
2065 l_int32 sbyte0, sbyte1, sbyte2, sbyte3, sbyte4, sbyte5, sbyte6, sbyte7, sum;
2066 l_uint32 *lines, *lined;
2067 
2068  /* i indexes the dest lines
2069  * k indexes the source lines
2070  * j indexes the src and dest bytes
2071  * We take 8 bytes from the source (in 8 lines of 8 pixels
2072  * each) and convert it into one 8 bpp byte of the dest. */
2073  for (i = 0, k = 0; i < hd; i++, k += 8) {
2074  lines = datas + k * wpls;
2075  lined = datad + i * wpld;
2076  for (j = 0; j < wd; j++) {
2077  sbyte0 = GET_DATA_BYTE(lines, j);
2078  sbyte1 = GET_DATA_BYTE(lines + wpls, j);
2079  sbyte2 = GET_DATA_BYTE(lines + 2 * wpls, j);
2080  sbyte3 = GET_DATA_BYTE(lines + 3 * wpls, j);
2081  sbyte4 = GET_DATA_BYTE(lines + 4 * wpls, j);
2082  sbyte5 = GET_DATA_BYTE(lines + 5 * wpls, j);
2083  sbyte6 = GET_DATA_BYTE(lines + 6 * wpls, j);
2084  sbyte7 = GET_DATA_BYTE(lines + 7 * wpls, j);
2085  sum = tab8[sbyte0] + tab8[sbyte1] +
2086  tab8[sbyte2] + tab8[sbyte3] +
2087  tab8[sbyte4] + tab8[sbyte5] +
2088  tab8[sbyte6] + tab8[sbyte7];
2089  SET_DATA_BYTE(lined, j, valtab[sum]);
2090  }
2091  }
2092 }
2093 
2094 
2106 static l_uint8 *
2108 {
2109 l_int32 i;
2110 l_uint8 *tab;
2111 
2112  tab = (l_uint8 *)LEPT_CALLOC(65, sizeof(l_uint8));
2113  for (i = 0; i < 65; i++)
2114  tab[i] = 0xff - (i * 255) / 64;
2115  return tab;
2116 }
2117 
2118 
2119 /*------------------------------------------------------------------*
2120  * Scale-to-gray 16x *
2121  *------------------------------------------------------------------*/
2144 static void
2145 scaleToGray16Low(l_uint32 *datad,
2146  l_int32 wd,
2147  l_int32 hd,
2148  l_int32 wpld,
2149  l_uint32 *datas,
2150  l_int32 wpls,
2151  l_int32 *tab8)
2152 {
2153 l_int32 i, j, k, m;
2154 l_int32 sum;
2155 l_uint32 *lines, *lined;
2156 
2157  /* i indexes the dest lines
2158  * k indexes the source lines
2159  * j indexes the dest bytes
2160  * m indexes the src bytes
2161  * We take 32 bytes from the source (in 16 lines of 16 pixels
2162  * each) and convert it into one 8 bpp byte of the dest. */
2163  for (i = 0, k = 0; i < hd; i++, k += 16) {
2164  lines = datas + k * wpls;
2165  lined = datad + i * wpld;
2166  for (j = 0; j < wd; j++) {
2167  m = 2 * j;
2168  sum = tab8[GET_DATA_BYTE(lines, m)];
2169  sum += tab8[GET_DATA_BYTE(lines, m + 1)];
2170  sum += tab8[GET_DATA_BYTE(lines + wpls, m)];
2171  sum += tab8[GET_DATA_BYTE(lines + wpls, m + 1)];
2172  sum += tab8[GET_DATA_BYTE(lines + 2 * wpls, m)];
2173  sum += tab8[GET_DATA_BYTE(lines + 2 * wpls, m + 1)];
2174  sum += tab8[GET_DATA_BYTE(lines + 3 * wpls, m)];
2175  sum += tab8[GET_DATA_BYTE(lines + 3 * wpls, m + 1)];
2176  sum += tab8[GET_DATA_BYTE(lines + 4 * wpls, m)];
2177  sum += tab8[GET_DATA_BYTE(lines + 4 * wpls, m + 1)];
2178  sum += tab8[GET_DATA_BYTE(lines + 5 * wpls, m)];
2179  sum += tab8[GET_DATA_BYTE(lines + 5 * wpls, m + 1)];
2180  sum += tab8[GET_DATA_BYTE(lines + 6 * wpls, m)];
2181  sum += tab8[GET_DATA_BYTE(lines + 6 * wpls, m + 1)];
2182  sum += tab8[GET_DATA_BYTE(lines + 7 * wpls, m)];
2183  sum += tab8[GET_DATA_BYTE(lines + 7 * wpls, m + 1)];
2184  sum += tab8[GET_DATA_BYTE(lines + 8 * wpls, m)];
2185  sum += tab8[GET_DATA_BYTE(lines + 8 * wpls, m + 1)];
2186  sum += tab8[GET_DATA_BYTE(lines + 9 * wpls, m)];
2187  sum += tab8[GET_DATA_BYTE(lines + 9 * wpls, m + 1)];
2188  sum += tab8[GET_DATA_BYTE(lines + 10 * wpls, m)];
2189  sum += tab8[GET_DATA_BYTE(lines + 10 * wpls, m + 1)];
2190  sum += tab8[GET_DATA_BYTE(lines + 11 * wpls, m)];
2191  sum += tab8[GET_DATA_BYTE(lines + 11 * wpls, m + 1)];
2192  sum += tab8[GET_DATA_BYTE(lines + 12 * wpls, m)];
2193  sum += tab8[GET_DATA_BYTE(lines + 12 * wpls, m + 1)];
2194  sum += tab8[GET_DATA_BYTE(lines + 13 * wpls, m)];
2195  sum += tab8[GET_DATA_BYTE(lines + 13 * wpls, m + 1)];
2196  sum += tab8[GET_DATA_BYTE(lines + 14 * wpls, m)];
2197  sum += tab8[GET_DATA_BYTE(lines + 14 * wpls, m + 1)];
2198  sum += tab8[GET_DATA_BYTE(lines + 15 * wpls, m)];
2199  sum += tab8[GET_DATA_BYTE(lines + 15 * wpls, m + 1)];
2200  sum = L_MIN(sum, 255);
2201  SET_DATA_BYTE(lined, j, 255 - sum);
2202  }
2203  }
2204 }
2205 
2206 
2207 
2208 /*------------------------------------------------------------------*
2209  * Grayscale mipmap *
2210  *------------------------------------------------------------------*/
2221 static l_int32
2222 scaleMipmapLow(l_uint32 *datad,
2223  l_int32 wd,
2224  l_int32 hd,
2225  l_int32 wpld,
2226  l_uint32 *datas1,
2227  l_int32 wpls1,
2228  l_uint32 *datas2,
2229  l_int32 wpls2,
2230  l_float32 red)
2231 {
2232 l_int32 i, j, val1, val2, val, row2, col2;
2233 l_int32 *srow, *scol;
2234 l_uint32 *lines1, *lines2, *lined;
2235 l_float32 ratio, w1, w2;
2236 
2237  /* Clear dest */
2238  memset(datad, 0, 4LL * wpld * hd);
2239 
2240  /* Each dest pixel at (j,i) is computed by interpolating
2241  between the two src images at the corresponding location.
2242  We store the UL corner locations of the square of
2243  src pixels in thelower-resolution image that correspond
2244  to dest pixel (j,i). The are labeled by the arrays
2245  srow[i], scol[j]. The UL corner locations of the higher
2246  resolution src pixels are obtained from these arrays
2247  by multiplying by 2. */
2248  if ((srow = (l_int32 *)LEPT_CALLOC(hd, sizeof(l_int32))) == NULL)
2249  return ERROR_INT("srow not made", __func__, 1);
2250  if ((scol = (l_int32 *)LEPT_CALLOC(wd, sizeof(l_int32))) == NULL) {
2251  LEPT_FREE(srow);
2252  return ERROR_INT("scol not made", __func__, 1);
2253  }
2254  ratio = 1. / (2. * red); /* 0.5 for red = 1, 1 for red = 0.5 */
2255  for (i = 0; i < hd; i++)
2256  srow[i] = (l_int32)(ratio * i);
2257  for (j = 0; j < wd; j++)
2258  scol[j] = (l_int32)(ratio * j);
2259 
2260  /* Get weights for linear interpolation: these are the
2261  * 'distances' of the dest image plane from the two
2262  * src image planes. */
2263  w1 = 2. * red - 1.; /* w1 --> 1 as red --> 1 */
2264  w2 = 1. - w1;
2265 
2266  /* For each dest pixel, compute linear interpolation */
2267  for (i = 0; i < hd; i++) {
2268  row2 = srow[i];
2269  lines1 = datas1 + 2 * row2 * wpls1;
2270  lines2 = datas2 + row2 * wpls2;
2271  lined = datad + i * wpld;
2272  for (j = 0; j < wd; j++) {
2273  col2 = scol[j];
2274  val1 = GET_DATA_BYTE(lines1, 2 * col2);
2275  val2 = GET_DATA_BYTE(lines2, col2);
2276  val = (l_int32)(w1 * val1 + w2 * val2);
2277  SET_DATA_BYTE(lined, j, val);
2278  }
2279  }
2280 
2281  LEPT_FREE(srow);
2282  LEPT_FREE(scol);
2283  return 0;
2284 }
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:164
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:212
#define SET_DATA_DIBIT(pdata, n, val)
Definition: arrayaccess.h:149
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
#define GET_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:145
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
#define SET_DATA_QBIT(pdata, n, val)
Definition: arrayaccess.h:168
PIX * pixExpandBinaryReplicate(PIX *pixs, l_int32 xfact, l_int32 yfact)
pixExpandBinaryReplicate()
Definition: binexpand.c:70
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1642
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:608
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1074
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:689
l_ok pixCopyColormap(PIX *pixd, const PIX *pixs)
pixCopyColormap()
Definition: pix1.c:795
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:582
l_ok pixSetBorderRingVal(PIX *pixs, l_int32 dist, l_uint32 val)
pixSetBorderRingVal()
Definition: pix2.c:1623
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition: pix2.c:2464
l_ok pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition: pix2.c:2669
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:799
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1346
l_ok pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition: pix2.c:2521
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:929
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2354
PIX * pixResizeToMatch(PIX *pixs, PIX *pixt, l_int32 w, l_int32 h)
pixResizeToMatch()
Definition: pix5.c:1279
@ L_ALPHA_CHANNEL
Definition: pix.h:331
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2345
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3246
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:250
PIX * pixScaleGrayLI(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleGrayLI()
Definition: scale1.c:762
PIX * pixScaleGeneral(PIX *pixs, l_float32 scalex, l_float32 scaley, l_float32 sharpfract, l_int32 sharpwidth)
pixScaleGeneral()
Definition: scale1.c:415
PIX * pixScaleBinary(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBinary()
Definition: scale1.c:2105
PIX * pixScaleSmooth(PIX *pix, l_float32 scalex, l_float32 scaley)
pixScaleSmooth()
Definition: scale1.c:1665
PIX * pixScaleToGray8(PIX *pixs)
pixScaleToGray8()
Definition: scale2.c:593
PIX * pixScaleToGrayFast(PIX *pixs, l_float32 scalefactor)
pixScaleToGrayFast()
Definition: scale2.c:317
PIX * pixScaleToGray3(PIX *pixs)
pixScaleToGray3()
Definition: scale2.c:442
static l_uint8 * makeValTabSG3(void)
makeValTabSG3()
Definition: scale2.c:1753
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:2145
PIX * pixScaleGrayMinMax2(PIX *pixs, l_int32 type)
pixScaleGrayMinMax2()
Definition: scale2.c:1102
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:1919
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:1794
PIX * pixScaleWithAlpha(PIX *pixs, l_float32 scalex, l_float32 scaley, PIX *pixg, l_float32 fract)
pixScaleWithAlpha()
Definition: scale2.c:1411
l_ok pixScaleAndTransferAlpha(PIX *pixd, PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleAndTransferAlpha()
Definition: scale2.c:1334
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:1511
static l_uint32 * makeSumTabSG2(void)
makeSumTabSG2()
Definition: scale2.c:1571
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:2055
static l_uint8 * makeValTabSG2(void)
makeValTabSG2()
Definition: scale2.c:1599
PIX * pixScaleGrayRankCascade(PIX *pixs, l_int32 level1, l_int32 level2, l_int32 level3, l_int32 level4)
pixScaleGrayRankCascade()
Definition: scale2.c:1183
PIX * pixScaleToGray6(PIX *pixs)
pixScaleToGray6()
Definition: scale2.c:547
PIX * pixScaleToGray2(PIX *pixs)
pixScaleToGray2()
Definition: scale2.c:386
PIX * pixScaleToGrayMipmap(PIX *pixs, l_float32 scalefactor)
pixScaleToGrayMipmap()
Definition: scale2.c:711
PIX * pixExpandReplicate(PIX *pixs, l_int32 factor)
pixExpandReplicate()
Definition: scale2.c:852
static l_uint32 * makeSumTabSG3(void)
makeSumTabSG3()
Definition: scale2.c:1726
PIX * pixScaleToGray16(PIX *pixs)
pixScaleToGray16()
Definition: scale2.c:640
static l_uint8 * makeValTabSG4(void)
makeValTabSG4()
Definition: scale2.c:1870
static l_uint8 * makeValTabSG6(void)
makeValTabSG6()
Definition: scale2.c:2015
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:1649
PIX * pixScaleGrayMinMax(PIX *pixs, l_int32 xfact, l_int32 yfact, l_int32 type)
pixScaleGrayMinMax()
Definition: scale2.c:997
static l_uint8 * makeValTabSG8(void)
makeValTabSG8()
Definition: scale2.c:2107
PIX * pixScaleMipmap(PIX *pixs1, PIX *pixs2, l_float32 scale)
pixScaleMipmap()
Definition: scale2.c:797
static l_uint32 * makeSumTabSG4(void)
makeSumTabSG4()
Definition: scale2.c:1843
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:2222
PIX * pixScaleToGray(PIX *pixs, l_float32 scalefactor)
pixScaleToGray()
Definition: scale2.c:208
PIX * pixScaleGrayRank2(PIX *pixs, l_int32 rank)
pixScaleGrayRank2()
Definition: scale2.c:1245
PIX * pixScaleToGray4(PIX *pixs)
pixScaleToGray4()
Definition: scale2.c:494
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306