Leptonica 1.82.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#ifdef HAVE_CONFIG_H
99#include <config_auto.h>
100#endif /* HAVE_CONFIG_H */
101
102#include <string.h>
103#include "allheaders.h"
104
105static 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);
108static l_uint32 *makeSumTabSG2(void);
109static l_uint8 *makeValTabSG2(void);
110static 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);
113static l_uint32 *makeSumTabSG3(void);
114static l_uint8 *makeValTabSG3(void);
115static 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);
118static l_uint32 *makeSumTabSG4(void);
119static l_uint8 *makeValTabSG4(void);
120static 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);
123static l_uint8 *makeValTabSG6(void);
124static 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);
127static l_uint8 *makeValTabSG8(void);
128static 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);
131static 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
135extern l_float32 AlphaMaskBorderVals[2];
136
137
138/*------------------------------------------------------------------*
139 * Scale-to-gray (1 bpp --> 8 bpp; arbitrary downscaling) *
140 *------------------------------------------------------------------*/
207PIX *
209 l_float32 scalefactor)
210{
211l_int32 w, h, minsrc, mindest;
212l_float32 mag, red;
213PIX *pixt, *pixd;
214
215 PROCNAME("pixScaleToGray");
216
217 if (!pixs)
218 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
219 if (pixGetDepth(pixs) != 1)
220 return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
221 if (scalefactor <= 0.0)
222 return (PIX *)ERROR_PTR("scalefactor <= 0.0", procName, NULL);
223 if (scalefactor >= 1.0)
224 return (PIX *)ERROR_PTR("scalefactor >= 1.0", procName, NULL);
225 pixGetDimensions(pixs, &w, &h, NULL);
226 minsrc = L_MIN(w, h);
227 mindest = (l_int32)((l_float32)minsrc * scalefactor);
228 if (mindest < 2)
229 return (PIX *)ERROR_PTR("scalefactor too small", procName, NULL);
230
231 if (scalefactor > 0.5) { /* see note (5) */
232 mag = 2.0 * scalefactor; /* will be < 2.0 */
233/* lept_stderr("2x with mag %7.3f\n", mag); */
234 if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
235 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
236 pixd = pixScaleToGray2(pixt);
237 } else if (scalefactor == 0.5) {
238 return pixd = pixScaleToGray2(pixs);
239 } else if (scalefactor > 0.33333) { /* see note (5) */
240 mag = 3.0 * scalefactor; /* will be < 1.5 */
241/* lept_stderr("3x with mag %7.3f\n", mag); */
242 if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
243 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
244 pixd = pixScaleToGray3(pixt);
245 } else if (scalefactor > 0.25) { /* see note (5) */
246 mag = 4.0 * scalefactor; /* will be < 1.3333 */
247/* lept_stderr("4x with mag %7.3f\n", mag); */
248 if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
249 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
250 pixd = pixScaleToGray4(pixt);
251 } else if (scalefactor == 0.25) {
252 return pixd = pixScaleToGray4(pixs);
253 } else if (scalefactor > 0.16667) { /* see note (5) */
254 mag = 6.0 * scalefactor; /* will be < 1.5 */
255/* lept_stderr("6x with mag %7.3f\n", mag); */
256 if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
257 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
258 pixd = pixScaleToGray6(pixt);
259 } else if (scalefactor == 0.16667) {
260 return pixd = pixScaleToGray6(pixs);
261 } else if (scalefactor > 0.125) { /* see note (5) */
262 mag = 8.0 * scalefactor; /* will be < 1.3333 */
263/* lept_stderr("8x with mag %7.3f\n", mag); */
264 if ((pixt = pixScaleBinary(pixs, mag, mag)) == NULL)
265 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
266 pixd = pixScaleToGray8(pixt);
267 } else if (scalefactor == 0.125) {
268 return pixd = pixScaleToGray8(pixs);
269 } else if (scalefactor > 0.0625) { /* see note (6) */
270 red = 8.0 * scalefactor; /* will be > 0.5 */
271/* lept_stderr("8x with red %7.3f\n", red); */
272 if ((pixt = pixScaleBinary(pixs, red, red)) == NULL)
273 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
274 pixd = pixScaleToGray8(pixt);
275 } else if (scalefactor == 0.0625) {
276 return pixd = pixScaleToGray16(pixs);
277 } else { /* see note (7) */
278 red = 16.0 * scalefactor; /* will be <= 1.0 */
279/* lept_stderr("16x with red %7.3f\n", red); */
280 if ((pixt = pixScaleToGray16(pixs)) == NULL)
281 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
282 if (red < 0.7)
283 pixd = pixScaleSmooth(pixt, red, red); /* see note (3) */
284 else
285 pixd = pixScaleGrayLI(pixt, red, red); /* see note (2) */
286 }
287
288 pixDestroy(&pixt);
289 if (!pixd)
290 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
291 pixCopyInputFormat(pixd, pixs);
292 return pixd;
293}
294
295
318PIX *
320 l_float32 scalefactor)
321{
322l_int32 w, h, minsrc, mindest;
323l_float32 eps, factor;
324PIX *pixt, *pixd;
325
326 PROCNAME("pixScaleToGrayFast");
327
328 if (!pixs)
329 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
330 if (pixGetDepth(pixs) != 1)
331 return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
332 if (scalefactor <= 0.0)
333 return (PIX *)ERROR_PTR("scalefactor <= 0.0", procName, NULL);
334 if (scalefactor >= 1.0)
335 return (PIX *)ERROR_PTR("scalefactor >= 1.0", procName, NULL);
336 pixGetDimensions(pixs, &w, &h, NULL);
337 minsrc = L_MIN(w, h);
338 mindest = (l_int32)((l_float32)minsrc * scalefactor);
339 if (mindest < 2)
340 return (PIX *)ERROR_PTR("scalefactor too small", procName, NULL);
341 eps = 0.0001;
342
343 /* Handle the special cases */
344 if (scalefactor > 0.5 - eps && scalefactor < 0.5 + eps)
345 return pixScaleToGray2(pixs);
346 else if (scalefactor > 0.33333 - eps && scalefactor < 0.33333 + eps)
347 return pixScaleToGray3(pixs);
348 else if (scalefactor > 0.25 - eps && scalefactor < 0.25 + eps)
349 return pixScaleToGray4(pixs);
350 else if (scalefactor > 0.16666 - eps && scalefactor < 0.16666 + eps)
351 return pixScaleToGray6(pixs);
352 else if (scalefactor > 0.125 - eps && scalefactor < 0.125 + eps)
353 return pixScaleToGray8(pixs);
354 else if (scalefactor > 0.0625 - eps && scalefactor < 0.0625 + eps)
355 return pixScaleToGray16(pixs);
356
357 if (scalefactor > 0.0625) { /* scale binary first */
358 factor = 2.0 * scalefactor;
359 if ((pixt = pixScaleBinary(pixs, factor, factor)) == NULL)
360 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
361 pixd = pixScaleToGray2(pixt);
362 } else { /* scalefactor < 0.0625; scale-to-gray first */
363 factor = 16.0 * scalefactor; /* will be < 1.0 */
364 if ((pixt = pixScaleToGray16(pixs)) == NULL)
365 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
366 if (factor < 0.7)
367 pixd = pixScaleSmooth(pixt, factor, factor);
368 else
369 pixd = pixScaleGrayLI(pixt, factor, factor);
370 }
371 pixDestroy(&pixt);
372 if (!pixd)
373 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
374 pixCopyInputFormat(pixd, pixs);
375 return pixd;
376}
377
378
379/*-----------------------------------------------------------------------*
380 * Scale-to-gray (1 bpp --> 8 bpp; integer downscaling) *
381 *-----------------------------------------------------------------------*/
389PIX *
391{
392l_uint8 *valtab;
393l_int32 ws, hs, wd, hd;
394l_int32 wpld, wpls;
395l_uint32 *sumtab;
396l_uint32 *datas, *datad;
397PIX *pixd;
398
399 PROCNAME("pixScaleToGray2");
400
401 if (!pixs)
402 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
403 if (pixGetDepth(pixs) != 1)
404 return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, NULL);
405
406 pixGetDimensions(pixs, &ws, &hs, NULL);
407 wd = ws / 2;
408 hd = hs / 2;
409 if (wd == 0 || hd == 0)
410 return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
411
412 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
413 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
414 pixSetPadBits(pixs, 0);
415 pixCopyInputFormat(pixd, pixs);
416 pixCopyResolution(pixd, pixs);
417 pixScaleResolution(pixd, 0.5, 0.5);
418 datas = pixGetData(pixs);
419 datad = pixGetData(pixd);
420 wpls = pixGetWpl(pixs);
421 wpld = pixGetWpl(pixd);
422
423 sumtab = makeSumTabSG2();
424 valtab = makeValTabSG2();
425 scaleToGray2Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
426 LEPT_FREE(sumtab);
427 LEPT_FREE(valtab);
428 return pixd;
429}
430
431
447PIX *
449{
450l_uint8 *valtab;
451l_int32 ws, hs, wd, hd;
452l_int32 wpld, wpls;
453l_uint32 *sumtab;
454l_uint32 *datas, *datad;
455PIX *pixd;
456
457 PROCNAME("pixScaleToGray3");
458
459 if (!pixs)
460 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
461 if (pixGetDepth(pixs) != 1)
462 return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
463
464 pixGetDimensions(pixs, &ws, &hs, NULL);
465 wd = (ws / 3) & 0xfffffff8; /* truncate to factor of 8 */
466 hd = hs / 3;
467 if (wd == 0 || hd == 0)
468 return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
469
470 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
471 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
472 pixCopyInputFormat(pixd, pixs);
473 pixCopyResolution(pixd, pixs);
474 pixScaleResolution(pixd, 0.33333, 0.33333);
475 datas = pixGetData(pixs);
476 datad = pixGetData(pixd);
477 wpls = pixGetWpl(pixs);
478 wpld = pixGetWpl(pixd);
479
480 sumtab = makeSumTabSG3();
481 valtab = makeValTabSG3();
482 scaleToGray3Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
483 LEPT_FREE(sumtab);
484 LEPT_FREE(valtab);
485 return pixd;
486}
487
488
501PIX *
503{
504l_uint8 *valtab;
505l_int32 ws, hs, wd, hd;
506l_int32 wpld, wpls;
507l_uint32 *sumtab;
508l_uint32 *datas, *datad;
509PIX *pixd;
510
511 PROCNAME("pixScaleToGray4");
512
513 if (!pixs)
514 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
515 if (pixGetDepth(pixs) != 1)
516 return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, NULL);
517
518 pixGetDimensions(pixs, &ws, &hs, NULL);
519 wd = (ws / 4) & 0xfffffffe; /* truncate to factor of 2 */
520 hd = hs / 4;
521 if (wd == 0 || hd == 0)
522 return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
523
524 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
525 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
526 pixCopyInputFormat(pixd, pixs);
527 pixCopyResolution(pixd, pixs);
528 pixScaleResolution(pixd, 0.25, 0.25);
529 datas = pixGetData(pixs);
530 datad = pixGetData(pixd);
531 wpls = pixGetWpl(pixs);
532 wpld = pixGetWpl(pixd);
533
534 sumtab = makeSumTabSG4();
535 valtab = makeValTabSG4();
536 scaleToGray4Low(datad, wd, hd, wpld, datas, wpls, sumtab, valtab);
537 LEPT_FREE(sumtab);
538 LEPT_FREE(valtab);
539 return pixd;
540}
541
542
543
556PIX *
558{
559l_uint8 *valtab;
560l_int32 ws, hs, wd, hd, wpld, wpls;
561l_int32 *tab8;
562l_uint32 *datas, *datad;
563PIX *pixd;
564
565 PROCNAME("pixScaleToGray6");
566
567 if (!pixs)
568 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
569 if (pixGetDepth(pixs) != 1)
570 return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
571
572 pixGetDimensions(pixs, &ws, &hs, NULL);
573 wd = (ws / 6) & 0xfffffff8; /* truncate to factor of 8 */
574 hd = hs / 6;
575 if (wd == 0 || hd == 0)
576 return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
577
578 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
579 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
580 pixCopyInputFormat(pixd, pixs);
581 pixCopyResolution(pixd, pixs);
582 pixScaleResolution(pixd, 0.16667, 0.16667);
583 datas = pixGetData(pixs);
584 datad = pixGetData(pixd);
585 wpls = pixGetWpl(pixs);
586 wpld = pixGetWpl(pixd);
587
588 tab8 = makePixelSumTab8();
589 valtab = makeValTabSG6();
590 scaleToGray6Low(datad, wd, hd, wpld, datas, wpls, tab8, valtab);
591 LEPT_FREE(tab8);
592 LEPT_FREE(valtab);
593 return pixd;
594}
595
596
604PIX *
606{
607l_uint8 *valtab;
608l_int32 ws, hs, wd, hd;
609l_int32 wpld, wpls;
610l_int32 *tab8;
611l_uint32 *datas, *datad;
612PIX *pixd;
613
614 PROCNAME("pixScaleToGray8");
615
616 if (!pixs)
617 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
618 if (pixGetDepth(pixs) != 1)
619 return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, NULL);
620
621 pixGetDimensions(pixs, &ws, &hs, NULL);
622 wd = ws / 8; /* truncate to nearest dest byte */
623 hd = hs / 8;
624 if (wd == 0 || hd == 0)
625 return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
626
627 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
628 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
629 pixCopyInputFormat(pixd, pixs);
630 pixCopyResolution(pixd, pixs);
631 pixScaleResolution(pixd, 0.125, 0.125);
632 datas = pixGetData(pixs);
633 datad = pixGetData(pixd);
634 wpls = pixGetWpl(pixs);
635 wpld = pixGetWpl(pixd);
636
637 tab8 = makePixelSumTab8();
638 valtab = makeValTabSG8();
639 scaleToGray8Low(datad, wd, hd, wpld, datas, wpls, tab8, valtab);
640 LEPT_FREE(tab8);
641 LEPT_FREE(valtab);
642 return pixd;
643}
644
645
653PIX *
655{
656l_int32 ws, hs, wd, hd;
657l_int32 wpld, wpls;
658l_int32 *tab8;
659l_uint32 *datas, *datad;
660PIX *pixd;
661
662 PROCNAME("pixScaleToGray16");
663
664 if (!pixs)
665 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
666 if (pixGetDepth(pixs) != 1)
667 return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, NULL);
668
669 pixGetDimensions(pixs, &ws, &hs, NULL);
670 wd = ws / 16;
671 hd = hs / 16;
672 if (wd == 0 || hd == 0)
673 return (PIX *)ERROR_PTR("pixs too small", procName, NULL);
674
675 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
676 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
677 pixCopyInputFormat(pixd, pixs);
678 pixCopyResolution(pixd, pixs);
679 pixScaleResolution(pixd, 0.0625, 0.0625);
680 datas = pixGetData(pixs);
681 datad = pixGetData(pixd);
682 wpls = pixGetWpl(pixs);
683 wpld = pixGetWpl(pixd);
684
685 tab8 = makePixelSumTab8();
686 scaleToGray16Low(datad, wd, hd, wpld, datas, wpls, tab8);
687 LEPT_FREE(tab8);
688 return pixd;
689}
690
691
692/*------------------------------------------------------------------*
693 * Scale-to-gray mipmap(1 bpp --> 8 bpp, arbitrary reduction) *
694 *------------------------------------------------------------------*/
726PIX *
728 l_float32 scalefactor)
729{
730l_int32 w, h, minsrc, mindest;
731l_float32 red;
732PIX *pixs1, *pixs2, *pixt, *pixd;
733
734 PROCNAME("pixScaleToGrayMipmap");
735
736 if (!pixs)
737 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
738 if (pixGetDepth(pixs) != 1)
739 return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
740 if (scalefactor <= 0.0)
741 return (PIX *)ERROR_PTR("scalefactor <= 0.0", procName, NULL);
742 if (scalefactor >= 1.0)
743 return (PIX *)ERROR_PTR("scalefactor >= 1.0", procName, NULL);
744 pixGetDimensions(pixs, &w, &h, NULL);
745 minsrc = L_MIN(w, h);
746 mindest = (l_int32)((l_float32)minsrc * scalefactor);
747 if (mindest < 2)
748 return (PIX *)ERROR_PTR("scalefactor too small", procName, NULL);
749
750 if (scalefactor > 0.5) {
751 pixs1 = pixConvert1To8(NULL, pixs, 255, 0);
752 pixs2 = pixScaleToGray2(pixs);
753 red = scalefactor;
754 } else if (scalefactor == 0.5) {
755 return pixScaleToGray2(pixs);
756 } else if (scalefactor > 0.25) {
757 pixs1 = pixScaleToGray2(pixs);
758 pixs2 = pixScaleToGray4(pixs);
759 red = 2. * scalefactor;
760 } else if (scalefactor == 0.25) {
761 return pixScaleToGray4(pixs);
762 } else if (scalefactor > 0.125) {
763 pixs1 = pixScaleToGray4(pixs);
764 pixs2 = pixScaleToGray8(pixs);
765 red = 4. * scalefactor;
766 } else if (scalefactor == 0.125) {
767 return pixScaleToGray8(pixs);
768 } else if (scalefactor > 0.0625) {
769 pixs1 = pixScaleToGray8(pixs);
770 pixs2 = pixScaleToGray16(pixs);
771 red = 8. * scalefactor;
772 } else if (scalefactor == 0.0625) {
773 return pixScaleToGray16(pixs);
774 } else { /* end of the pyramid; just do it */
775 red = 16.0 * scalefactor; /* will be <= 1.0 */
776 if ((pixt = pixScaleToGray16(pixs)) == NULL)
777 return (PIX *)ERROR_PTR("pixt not made", procName, NULL);
778 if (red < 0.7)
779 pixd = pixScaleSmooth(pixt, red, red);
780 else
781 pixd = pixScaleGrayLI(pixt, red, red);
782 pixDestroy(&pixt);
783 return pixd;
784 }
785
786 pixd = pixScaleMipmap(pixs1, pixs2, red);
787 pixCopyInputFormat(pixd, pixs);
788
789 pixDestroy(&pixs1);
790 pixDestroy(&pixs2);
791 return pixd;
792}
793
794
795/*------------------------------------------------------------------*
796 * Grayscale scaling using mipmap *
797 *------------------------------------------------------------------*/
814PIX *
816 PIX *pixs2,
817 l_float32 scale)
818{
819l_int32 ws1, hs1, ws2, hs2, wd, hd, wpls1, wpls2, wpld;
820l_uint32 *datas1, *datas2, *datad;
821PIX *pixd;
822
823 PROCNAME("pixScaleMipmap");
824
825 if (!pixs1 || pixGetDepth(pixs1) != 8 || pixGetColormap(pixs1))
826 return (PIX *)ERROR_PTR("pixs1 underdefined, not 8 bpp, or cmapped",
827 procName, NULL);
828 if (!pixs2 || pixGetDepth(pixs2) != 8 || pixGetColormap(pixs2))
829 return (PIX *)ERROR_PTR("pixs2 underdefined, not 8 bpp, or cmapped",
830 procName, NULL);
831 pixGetDimensions(pixs1, &ws1, &hs1, NULL);
832 pixGetDimensions(pixs2, &ws2, &hs2, NULL);
833 if (scale > 1.0 || scale < 0.5)
834 return (PIX *)ERROR_PTR("scale not in [0.5, 1.0]", procName, NULL);
835 if (ws1 < 2 * ws2)
836 return (PIX *)ERROR_PTR("invalid width ratio", procName, NULL);
837 if (hs1 < 2 * hs2)
838 return (PIX *)ERROR_PTR("invalid height ratio", procName, NULL);
839
840 /* Generate wd and hd from the lower resolution dimensions,
841 * to guarantee staying within both src images */
842 datas1 = pixGetData(pixs1);
843 wpls1 = pixGetWpl(pixs1);
844 datas2 = pixGetData(pixs2);
845 wpls2 = pixGetWpl(pixs2);
846 wd = (l_int32)(2. * scale * pixGetWidth(pixs2));
847 hd = (l_int32)(2. * scale * pixGetHeight(pixs2));
848 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
849 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
850 pixCopyInputFormat(pixd, pixs1);
851 pixCopyResolution(pixd, pixs1);
852 pixScaleResolution(pixd, scale, scale);
853 datad = pixGetData(pixd);
854 wpld = pixGetWpl(pixd);
855
856 scaleMipmapLow(datad, wd, hd, wpld, datas1, wpls1, datas2, wpls2, scale);
857 return pixd;
858}
859
860
861/*------------------------------------------------------------------*
862 * Replicated (integer) expansion *
863 *------------------------------------------------------------------*/
871PIX *
873 l_int32 factor)
874{
875l_int32 w, h, d, wd, hd, wpls, wpld, start, i, j, k;
876l_uint8 sval;
877l_uint16 sval16;
878l_uint32 sval32;
879l_uint32 *lines, *datas, *lined, *datad;
880PIX *pixd;
881
882 PROCNAME("pixExpandReplicate");
883
884 if (!pixs)
885 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
886 pixGetDimensions(pixs, &w, &h, &d);
887 if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
888 return (PIX *)ERROR_PTR("depth not in {1,2,4,8,16,32}", procName, NULL);
889 if (factor <= 0)
890 return (PIX *)ERROR_PTR("factor <= 0; invalid", procName, NULL);
891 if (factor == 1)
892 return pixCopy(NULL, pixs);
893
894 if (d == 1)
895 return pixExpandBinaryReplicate(pixs, factor, factor);
896
897 wd = factor * w;
898 hd = factor * h;
899 if ((pixd = pixCreate(wd, hd, d)) == NULL)
900 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
901 pixCopyColormap(pixd, pixs);
902 pixCopyInputFormat(pixd, pixs);
903 pixCopyResolution(pixd, pixs);
904 pixScaleResolution(pixd, (l_float32)factor, (l_float32)factor);
905 datas = pixGetData(pixs);
906 wpls = pixGetWpl(pixs);
907 datad = pixGetData(pixd);
908 wpld = pixGetWpl(pixd);
909
910 switch (d) {
911 case 2:
912 for (i = 0; i < h; i++) {
913 lines = datas + i * wpls;
914 lined = datad + factor * i * wpld;
915 for (j = 0; j < w; j++) {
916 sval = GET_DATA_DIBIT(lines, j);
917 start = factor * j;
918 for (k = 0; k < factor; k++)
919 SET_DATA_DIBIT(lined, start + k, sval);
920 }
921 for (k = 1; k < factor; k++)
922 memcpy(lined + k * wpld, lined, 4 * wpld);
923 }
924 break;
925 case 4:
926 for (i = 0; i < h; i++) {
927 lines = datas + i * wpls;
928 lined = datad + factor * i * wpld;
929 for (j = 0; j < w; j++) {
930 sval = GET_DATA_QBIT(lines, j);
931 start = factor * j;
932 for (k = 0; k < factor; k++)
933 SET_DATA_QBIT(lined, start + k, sval);
934 }
935 for (k = 1; k < factor; k++)
936 memcpy(lined + k * wpld, lined, 4 * wpld);
937 }
938 break;
939 case 8:
940 for (i = 0; i < h; i++) {
941 lines = datas + i * wpls;
942 lined = datad + factor * i * wpld;
943 for (j = 0; j < w; j++) {
944 sval = GET_DATA_BYTE(lines, j);
945 start = factor * j;
946 for (k = 0; k < factor; k++)
947 SET_DATA_BYTE(lined, start + k, sval);
948 }
949 for (k = 1; k < factor; k++)
950 memcpy(lined + k * wpld, lined, 4 * wpld);
951 }
952 break;
953 case 16:
954 for (i = 0; i < h; i++) {
955 lines = datas + i * wpls;
956 lined = datad + factor * i * wpld;
957 for (j = 0; j < w; j++) {
958 sval16 = GET_DATA_TWO_BYTES(lines, j);
959 start = factor * j;
960 for (k = 0; k < factor; k++)
961 SET_DATA_TWO_BYTES(lined, start + k, sval16);
962 }
963 for (k = 1; k < factor; k++)
964 memcpy(lined + k * wpld, lined, 4 * wpld);
965 }
966 break;
967 case 32:
968 for (i = 0; i < h; i++) {
969 lines = datas + i * wpls;
970 lined = datad + factor * i * wpld;
971 for (j = 0; j < w; j++) {
972 sval32 = *(lines + j);
973 start = factor * j;
974 for (k = 0; k < factor; k++)
975 *(lined + start + k) = sval32;
976 }
977 for (k = 1; k < factor; k++)
978 memcpy(lined + k * wpld, lined, 4 * wpld);
979 }
980 break;
981 default:
982 lept_stderr("invalid depth\n");
983 }
984
985 if (d == 32 && pixGetSpp(pixs) == 4)
986 pixScaleAndTransferAlpha(pixd, pixs, (l_float32)factor,
987 (l_float32)factor);
988 return pixd;
989}
990
991
992/*-----------------------------------------------------------------------*
993 * Downscaling using min or max *
994 *-----------------------------------------------------------------------*/
1018PIX *
1020 l_int32 xfact,
1021 l_int32 yfact,
1022 l_int32 type)
1023{
1024l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k, m;
1025l_int32 minval, maxval, val;
1026l_uint32 *datas, *datad, *lines, *lined;
1027PIX *pixd;
1028
1029 PROCNAME("pixScaleGrayMinMax");
1030
1031 if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1032 return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1033 procName, NULL);
1034 pixGetDimensions(pixs, &ws, &hs, NULL);
1035 if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX &&
1036 type != L_CHOOSE_MAXDIFF)
1037 return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1038 if (xfact < 1 || yfact < 1)
1039 return (PIX *)ERROR_PTR("xfact and yfact must be >= 1", procName, NULL);
1040
1041 if (xfact == 2 && yfact == 2)
1042 return pixScaleGrayMinMax2(pixs, type);
1043
1044 wd = ws / xfact;
1045 if (wd == 0) { /* single tile */
1046 wd = 1;
1047 xfact = ws;
1048 }
1049 hd = hs / yfact;
1050 if (hd == 0) { /* single tile */
1051 hd = 1;
1052 yfact = hs;
1053 }
1054 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1055 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1056 pixCopyInputFormat(pixd, pixs);
1057 datas = pixGetData(pixs);
1058 datad = pixGetData(pixd);
1059 wpls = pixGetWpl(pixs);
1060 wpld = pixGetWpl(pixd);
1061 for (i = 0; i < hd; i++) {
1062 lined = datad + i * wpld;
1063 for (j = 0; j < wd; j++) {
1064 if (type == L_CHOOSE_MIN || type == L_CHOOSE_MAXDIFF) {
1065 minval = 255;
1066 for (k = 0; k < yfact; k++) {
1067 lines = datas + (yfact * i + k) * wpls;
1068 for (m = 0; m < xfact; m++) {
1069 val = GET_DATA_BYTE(lines, xfact * j + m);
1070 if (val < minval)
1071 minval = val;
1072 }
1073 }
1074 }
1075 if (type == L_CHOOSE_MAX || type == L_CHOOSE_MAXDIFF) {
1076 maxval = 0;
1077 for (k = 0; k < yfact; k++) {
1078 lines = datas + (yfact * i + k) * wpls;
1079 for (m = 0; m < xfact; m++) {
1080 val = GET_DATA_BYTE(lines, xfact * j + m);
1081 if (val > maxval)
1082 maxval = val;
1083 }
1084 }
1085 }
1086 if (type == L_CHOOSE_MIN)
1087 SET_DATA_BYTE(lined, j, minval);
1088 else if (type == L_CHOOSE_MAX)
1089 SET_DATA_BYTE(lined, j, maxval);
1090 else /* type == L_CHOOSE_MAXDIFF */
1091 SET_DATA_BYTE(lined, j, maxval - minval);
1092 }
1093 }
1094
1095 return pixd;
1096}
1097
1098
1125PIX *
1127 l_int32 type)
1128{
1129l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k;
1130l_int32 minval, maxval;
1131l_int32 val[4];
1132l_uint32 *datas, *datad, *lines, *lined;
1133PIX *pixd;
1134
1135 PROCNAME("pixScaleGrayMinMax2");
1136
1137 if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1138 return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1139 procName, NULL);
1140 pixGetDimensions(pixs, &ws, &hs, NULL);
1141 if (ws < 2 || hs < 2)
1142 return (PIX *)ERROR_PTR("too small: ws < 2 or hs < 2", procName, NULL);
1143 if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX &&
1144 type != L_CHOOSE_MAXDIFF)
1145 return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1146
1147 wd = ws / 2;
1148 hd = hs / 2;
1149 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1150 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1151 pixCopyInputFormat(pixd, pixs);
1152 datas = pixGetData(pixs);
1153 datad = pixGetData(pixd);
1154 wpls = pixGetWpl(pixs);
1155 wpld = pixGetWpl(pixd);
1156 for (i = 0; i < hd; i++) {
1157 lines = datas + 2 * i * wpls;
1158 lined = datad + i * wpld;
1159 for (j = 0; j < wd; j++) {
1160 val[0] = GET_DATA_BYTE(lines, 2 * j);
1161 val[1] = GET_DATA_BYTE(lines, 2 * j + 1);
1162 val[2] = GET_DATA_BYTE(lines + wpls, 2 * j);
1163 val[3] = GET_DATA_BYTE(lines + wpls, 2 * j + 1);
1164 if (type == L_CHOOSE_MIN || type == L_CHOOSE_MAXDIFF) {
1165 minval = 255;
1166 for (k = 0; k < 4; k++) {
1167 if (val[k] < minval)
1168 minval = val[k];
1169 }
1170 }
1171 if (type == L_CHOOSE_MAX || type == L_CHOOSE_MAXDIFF) {
1172 maxval = 0;
1173 for (k = 0; k < 4; k++) {
1174 if (val[k] > maxval)
1175 maxval = val[k];
1176 }
1177 }
1178 if (type == L_CHOOSE_MIN)
1179 SET_DATA_BYTE(lined, j, minval);
1180 else if (type == L_CHOOSE_MAX)
1181 SET_DATA_BYTE(lined, j, maxval);
1182 else /* type == L_CHOOSE_MAXDIFF */
1183 SET_DATA_BYTE(lined, j, maxval - minval);
1184 }
1185 }
1186
1187 return pixd;
1188}
1189
1190
1191/*-----------------------------------------------------------------------*
1192 * Grayscale downscaling using rank value *
1193 *-----------------------------------------------------------------------*/
1208PIX *
1210 l_int32 level1,
1211 l_int32 level2,
1212 l_int32 level3,
1213 l_int32 level4)
1214{
1215PIX *pixt1, *pixt2, *pixt3, *pixt4;
1216
1217 PROCNAME("pixScaleGrayRankCascade");
1218
1219 if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1220 return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1221 procName, NULL);
1222 if (level1 > 4 || level2 > 4 || level3 > 4 || level4 > 4)
1223 return (PIX *)ERROR_PTR("levels must not exceed 4", procName, NULL);
1224
1225 if (level1 <= 0) {
1226 L_WARNING("no reduction because level1 not > 0\n", procName);
1227 return pixCopy(NULL, pixs);
1228 }
1229
1230 pixt1 = pixScaleGrayRank2(pixs, level1);
1231 if (level2 <= 0)
1232 return pixt1;
1233
1234 pixt2 = pixScaleGrayRank2(pixt1, level2);
1235 pixDestroy(&pixt1);
1236 if (level3 <= 0)
1237 return pixt2;
1238
1239 pixt3 = pixScaleGrayRank2(pixt2, level3);
1240 pixDestroy(&pixt2);
1241 if (level4 <= 0)
1242 return pixt3;
1243
1244 pixt4 = pixScaleGrayRank2(pixt3, level4);
1245 pixDestroy(&pixt3);
1246 return pixt4;
1247}
1248
1249
1272PIX *
1274 l_int32 rank)
1275{
1276l_int32 ws, hs, wd, hd, wpls, wpld, i, j, k, m;
1277l_int32 minval, maxval, rankval, minindex, maxindex;
1278l_int32 val[4];
1279l_int32 midval[4]; /* should only use 2 of these */
1280l_uint32 *datas, *datad, *lines, *lined;
1281PIX *pixd;
1282
1283 PROCNAME("pixScaleGrayRank2");
1284
1285 if (!pixs || pixGetDepth(pixs) != 8 || pixGetColormap(pixs))
1286 return (PIX *)ERROR_PTR("pixs undefined, not 8 bpp, or cmapped",
1287 procName, NULL);
1288 if (rank < 1 || rank > 4)
1289 return (PIX *)ERROR_PTR("invalid rank", procName, NULL);
1290
1291 if (rank == 1)
1292 return pixScaleGrayMinMax2(pixs, L_CHOOSE_MIN);
1293 if (rank == 4)
1294 return pixScaleGrayMinMax2(pixs, L_CHOOSE_MAX);
1295
1296 pixGetDimensions(pixs, &ws, &hs, NULL);
1297 wd = ws / 2;
1298 hd = hs / 2;
1299 if ((pixd = pixCreate(wd, hd, 8)) == NULL)
1300 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1301 pixCopyInputFormat(pixd, pixs);
1302 datas = pixGetData(pixs);
1303 datad = pixGetData(pixd);
1304 wpls = pixGetWpl(pixs);
1305 wpld = pixGetWpl(pixd);
1306 for (i = 0; i < hd; i++) {
1307 lines = datas + 2 * i * wpls;
1308 lined = datad + i * wpld;
1309 for (j = 0; j < wd; j++) {
1310 val[0] = GET_DATA_BYTE(lines, 2 * j);
1311 val[1] = GET_DATA_BYTE(lines, 2 * j + 1);
1312 val[2] = GET_DATA_BYTE(lines + wpls, 2 * j);
1313 val[3] = GET_DATA_BYTE(lines + wpls, 2 * j + 1);
1314 minval = maxval = val[0];
1315 minindex = maxindex = 0;
1316 for (k = 1; k < 4; k++) {
1317 if (val[k] < minval) {
1318 minval = val[k];
1319 minindex = k;
1320 continue;
1321 }
1322 if (val[k] > maxval) {
1323 maxval = val[k];
1324 maxindex = k;
1325 }
1326 }
1327 for (k = 0, m = 0; k < 4; k++) {
1328 if (k == minindex || k == maxindex)
1329 continue;
1330 midval[m++] = val[k];
1331 }
1332 if (m > 2) /* minval == maxval; all val[k] are the same */
1333 rankval = minval;
1334 else if (rank == 2)
1335 rankval = L_MIN(midval[0], midval[1]);
1336 else /* rank == 3 */
1337 rankval = L_MAX(midval[0], midval[1]);
1338 SET_DATA_BYTE(lined, j, rankval);
1339 }
1340 }
1341
1342 return pixd;
1343}
1344
1345
1346/*------------------------------------------------------------------------*
1347 * Helper function for transferring alpha with scaling *
1348 *------------------------------------------------------------------------*/
1363l_ok
1365 PIX *pixs,
1366 l_float32 scalex,
1367 l_float32 scaley)
1368{
1369PIX *pix1, *pix2;
1370
1371 PROCNAME("pixScaleAndTransferAlpha");
1372
1373 if (!pixs || !pixd)
1374 return ERROR_INT("pixs and pixd not both defined", procName, 1);
1375 if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
1376 return ERROR_INT("pixs not 32 bpp and 4 spp", procName, 1);
1377 if (pixGetDepth(pixd) != 32)
1378 return ERROR_INT("pixd not 32 bpp", procName, 1);
1379
1380 if (scalex == 1.0 && scaley == 1.0) {
1382 return 0;
1383 }
1384
1385 pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
1386 pix2 = pixScale(pix1, scalex, scaley);
1388 pixDestroy(&pix1);
1389 pixDestroy(&pix2);
1390 return 0;
1391}
1392
1393
1394/*------------------------------------------------------------------------*
1395 * RGB scaling including alpha (blend) component and gamma transform *
1396 *------------------------------------------------------------------------*/
1442PIX *
1444 l_float32 scalex,
1445 l_float32 scaley,
1446 PIX *pixg,
1447 l_float32 fract)
1448{
1449l_int32 ws, hs, d, spp;
1450PIX *pixd, *pix32, *pixg2, *pixgs;
1451
1452 PROCNAME("pixScaleWithAlpha");
1453
1454 if (!pixs)
1455 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1456 pixGetDimensions(pixs, &ws, &hs, &d);
1457 if (d != 32 && !pixGetColormap(pixs))
1458 return (PIX *)ERROR_PTR("pixs not cmapped or 32 bpp", procName, NULL);
1459 if (scalex <= 0.0 || scaley <= 0.0)
1460 return (PIX *)ERROR_PTR("scale factor <= 0.0", procName, NULL);
1461 if (pixg && pixGetDepth(pixg) != 8) {
1462 L_WARNING("pixg not 8 bpp; using 'fract' transparent alpha\n",
1463 procName);
1464 pixg = NULL;
1465 }
1466 if (!pixg && (fract < 0.0 || fract > 1.0)) {
1467 L_WARNING("invalid fract; using fully opaque\n", procName);
1468 fract = 1.0;
1469 }
1470 if (!pixg && fract == 0.0)
1471 L_WARNING("transparent alpha; image will not be blended\n", procName);
1472
1473 /* Make sure input to scaling is 32 bpp rgb, and scale it */
1474 if (d != 32)
1475 pix32 = pixConvertTo32(pixs);
1476 else
1477 pix32 = pixClone(pixs);
1478 spp = pixGetSpp(pix32);
1479 pixSetSpp(pix32, 3); /* ignore the alpha channel for scaling */
1480 pixd = pixScale(pix32, scalex, scaley);
1481 pixSetSpp(pix32, spp); /* restore initial value in case it's a clone */
1482 pixDestroy(&pix32);
1483
1484 /* Set up alpha layer with a fading border and scale it */
1485 if (!pixg) {
1486 pixg2 = pixCreate(ws, hs, 8);
1487 if (fract == 1.0)
1488 pixSetAll(pixg2);
1489 else if (fract > 0.0)
1490 pixSetAllArbitrary(pixg2, (l_int32)(255.0 * fract));
1491 } else {
1492 pixg2 = pixResizeToMatch(pixg, NULL, ws, hs);
1493 }
1494 if (ws > 10 && hs > 10) { /* see note 4 */
1495 pixSetBorderRingVal(pixg2, 1,
1496 (l_int32)(255.0 * fract * AlphaMaskBorderVals[0]));
1497 pixSetBorderRingVal(pixg2, 2,
1498 (l_int32)(255.0 * fract * AlphaMaskBorderVals[1]));
1499 }
1500 pixgs = pixScaleGeneral(pixg2, scalex, scaley, 0.0, 0);
1501
1502 /* Combine into a 4 spp result */
1503 pixSetRGBComponent(pixd, pixgs, L_ALPHA_CHANNEL);
1504 pixCopyInputFormat(pixd, pixs);
1505
1506 pixDestroy(&pixg2);
1507 pixDestroy(&pixgs);
1508 return pixd;
1509}
1510
1511
1512/* ================================================================ *
1513 * Low level static functions *
1514 * ================================================================ */
1515
1516/*------------------------------------------------------------------*
1517 * Scale-to-gray 2x *
1518 *------------------------------------------------------------------*/
1544static void
1545scaleToGray2Low(l_uint32 *datad,
1546 l_int32 wd,
1547 l_int32 hd,
1548 l_int32 wpld,
1549 l_uint32 *datas,
1550 l_int32 wpls,
1551 l_uint32 *sumtab,
1552 l_uint8 *valtab)
1553{
1554l_int32 i, j, l, k, m, wd4, extra;
1555l_uint32 sbyte1, sbyte2, sum;
1556l_uint32 *lines, *lined;
1557
1558 /* i indexes the dest lines
1559 * l indexes the source lines
1560 * j indexes the dest bytes
1561 * k indexes the source bytes
1562 * We take two bytes from the source (in 2 lines of 8 pixels
1563 * each) and convert them into four 8 bpp bytes of the dest. */
1564 wd4 = wd & 0xfffffffc;
1565 extra = wd - wd4;
1566 for (i = 0, l = 0; i < hd; i++, l += 2) {
1567 lines = datas + l * wpls;
1568 lined = datad + i * wpld;
1569 for (j = 0, k = 0; j < wd4; j += 4, k++) {
1570 sbyte1 = GET_DATA_BYTE(lines, k);
1571 sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1572 sum = sumtab[sbyte1] + sumtab[sbyte2];
1573 SET_DATA_BYTE(lined, j, valtab[sum >> 24]);
1574 SET_DATA_BYTE(lined, j + 1, valtab[(sum >> 16) & 0xff]);
1575 SET_DATA_BYTE(lined, j + 2, valtab[(sum >> 8) & 0xff]);
1576 SET_DATA_BYTE(lined, j + 3, valtab[sum & 0xff]);
1577 }
1578 if (extra > 0) {
1579 sbyte1 = GET_DATA_BYTE(lines, k);
1580 sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1581 sum = sumtab[sbyte1] + sumtab[sbyte2];
1582 for (m = 0; m < extra; m++) {
1583 SET_DATA_BYTE(lined, j + m,
1584 valtab[((sum >> (24 - 8 * m)) & 0xff)]);
1585 }
1586 }
1587
1588 }
1589}
1590
1591
1604static l_uint32 *
1606{
1607l_int32 i;
1608l_int32 sum[] = {0, 1, 1, 2};
1609l_uint32 *tab;
1610
1611 PROCNAME("makeSumTabSG2");
1612
1613 /* Pack the four sums separately in four bytes */
1614 tab = (l_uint32 *)LEPT_CALLOC(256, sizeof(l_uint32));
1615 for (i = 0; i < 256; i++) {
1616 tab[i] = (sum[i & 0x3] | sum[(i >> 2) & 0x3] << 8 |
1617 sum[(i >> 4) & 0x3] << 16 | sum[(i >> 6) & 0x3] << 24);
1618 }
1619 return tab;
1620}
1621
1622
1634static l_uint8 *
1636{
1637l_int32 i;
1638l_uint8 *tab;
1639
1640 PROCNAME("makeValTabSG2");
1641
1642 tab = (l_uint8 *)LEPT_CALLOC(5, sizeof(l_uint8));
1643 for (i = 0; i < 5; i++)
1644 tab[i] = 255 - (i * 255) / 4;
1645 return tab;
1646}
1647
1648
1649/*------------------------------------------------------------------*
1650 * Scale-to-gray 3x *
1651 *------------------------------------------------------------------*/
1686static void
1687scaleToGray3Low(l_uint32 *datad,
1688 l_int32 wd,
1689 l_int32 hd,
1690 l_int32 wpld,
1691 l_uint32 *datas,
1692 l_int32 wpls,
1693 l_uint32 *sumtab,
1694 l_uint8 *valtab)
1695{
1696l_int32 i, j, l, k;
1697l_uint32 threebytes1, threebytes2, threebytes3, sum;
1698l_uint32 *lines, *lined;
1699
1700 /* i indexes the dest lines
1701 * l indexes the source lines
1702 * j indexes the dest bytes
1703 * k indexes the source bytes
1704 * We take 9 bytes from the source (72 binary pixels
1705 * in three lines of 24 pixels each) and convert it
1706 * into 8 bytes of the dest (8 8bpp pixels in one line) */
1707 for (i = 0, l = 0; i < hd; i++, l += 3) {
1708 lines = datas + l * wpls;
1709 lined = datad + i * wpld;
1710 for (j = 0, k = 0; j < wd; j += 8, k += 3) {
1711 threebytes1 = (GET_DATA_BYTE(lines, k) << 16) |
1712 (GET_DATA_BYTE(lines, k + 1) << 8) |
1713 GET_DATA_BYTE(lines, k + 2);
1714 threebytes2 = (GET_DATA_BYTE(lines + wpls, k) << 16) |
1715 (GET_DATA_BYTE(lines + wpls, k + 1) << 8) |
1716 GET_DATA_BYTE(lines + wpls, k + 2);
1717 threebytes3 = (GET_DATA_BYTE(lines + 2 * wpls, k) << 16) |
1718 (GET_DATA_BYTE(lines + 2 * wpls, k + 1) << 8) |
1719 GET_DATA_BYTE(lines + 2 * wpls, k + 2);
1720
1721 sum = sumtab[(threebytes1 >> 18)] +
1722 sumtab[(threebytes2 >> 18)] +
1723 sumtab[(threebytes3 >> 18)];
1724 SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 2)]);
1725 SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1726
1727 sum = sumtab[((threebytes1 >> 12) & 0x3f)] +
1728 sumtab[((threebytes2 >> 12) & 0x3f)] +
1729 sumtab[((threebytes3 >> 12) & 0x3f)];
1730 SET_DATA_BYTE(lined, j + 2, valtab[GET_DATA_BYTE(&sum, 2)]);
1731 SET_DATA_BYTE(lined, j + 3, valtab[GET_DATA_BYTE(&sum, 3)]);
1732
1733 sum = sumtab[((threebytes1 >> 6) & 0x3f)] +
1734 sumtab[((threebytes2 >> 6) & 0x3f)] +
1735 sumtab[((threebytes3 >> 6) & 0x3f)];
1736 SET_DATA_BYTE(lined, j + 4, valtab[GET_DATA_BYTE(&sum, 2)]);
1737 SET_DATA_BYTE(lined, j + 5, valtab[GET_DATA_BYTE(&sum, 3)]);
1738
1739 sum = sumtab[(threebytes1 & 0x3f)] +
1740 sumtab[(threebytes2 & 0x3f)] +
1741 sumtab[(threebytes3 & 0x3f)];
1742 SET_DATA_BYTE(lined, j + 6, valtab[GET_DATA_BYTE(&sum, 2)]);
1743 SET_DATA_BYTE(lined, j + 7, valtab[GET_DATA_BYTE(&sum, 3)]);
1744 }
1745 }
1746}
1747
1748
1749
1763static l_uint32 *
1765{
1766l_int32 i;
1767l_int32 sum[] = {0, 1, 1, 2, 1, 2, 2, 3};
1768l_uint32 *tab;
1769
1770 PROCNAME("makeSumTabSG3");
1771
1772 /* Pack the two sums separately in two bytes */
1773 tab = (l_uint32 *)LEPT_CALLOC(64, sizeof(l_uint32));
1774 for (i = 0; i < 64; i++) {
1775 tab[i] = (sum[i & 0x07]) | (sum[(i >> 3) & 0x07] << 8);
1776 }
1777 return tab;
1778}
1779
1780
1792static l_uint8 *
1794{
1795l_int32 i;
1796l_uint8 *tab;
1797
1798 PROCNAME("makeValTabSG3");
1799
1800 tab = (l_uint8 *)LEPT_CALLOC(10, sizeof(l_uint8));
1801 for (i = 0; i < 10; i++)
1802 tab[i] = 0xff - (i * 255) / 9;
1803 return tab;
1804}
1805
1806
1807/*------------------------------------------------------------------*
1808 * Scale-to-gray 4x *
1809 *------------------------------------------------------------------*/
1835static void
1836scaleToGray4Low(l_uint32 *datad,
1837 l_int32 wd,
1838 l_int32 hd,
1839 l_int32 wpld,
1840 l_uint32 *datas,
1841 l_int32 wpls,
1842 l_uint32 *sumtab,
1843 l_uint8 *valtab)
1844{
1845l_int32 i, j, l, k;
1846l_uint32 sbyte1, sbyte2, sbyte3, sbyte4, sum;
1847l_uint32 *lines, *lined;
1848
1849 /* i indexes the dest lines
1850 * l indexes the source lines
1851 * j indexes the dest bytes
1852 * k indexes the source bytes
1853 * We take four bytes from the source (in 4 lines of 8 pixels
1854 * each) and convert it into two 8 bpp bytes of the dest. */
1855 for (i = 0, l = 0; i < hd; i++, l += 4) {
1856 lines = datas + l * wpls;
1857 lined = datad + i * wpld;
1858 for (j = 0, k = 0; j < wd; j += 2, k++) {
1859 sbyte1 = GET_DATA_BYTE(lines, k);
1860 sbyte2 = GET_DATA_BYTE(lines + wpls, k);
1861 sbyte3 = GET_DATA_BYTE(lines + 2 * wpls, k);
1862 sbyte4 = GET_DATA_BYTE(lines + 3 * wpls, k);
1863 sum = sumtab[sbyte1] + sumtab[sbyte2] +
1864 sumtab[sbyte3] + sumtab[sbyte4];
1865 SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 2)]);
1866 SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
1867 }
1868 }
1869}
1870
1871
1884static l_uint32 *
1886{
1887l_int32 i;
1888l_int32 sum[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1889l_uint32 *tab;
1890
1891 PROCNAME("makeSumTabSG4");
1892
1893 /* Pack the two sums separately in two bytes */
1894 tab = (l_uint32 *)LEPT_CALLOC(256, sizeof(l_uint32));
1895 for (i = 0; i < 256; i++) {
1896 tab[i] = (sum[i & 0xf]) | (sum[(i >> 4) & 0xf] << 8);
1897 }
1898 return tab;
1899}
1900
1901
1913static l_uint8 *
1915{
1916l_int32 i;
1917l_uint8 *tab;
1918
1919 PROCNAME("makeValTabSG4");
1920
1921 tab = (l_uint8 *)LEPT_CALLOC(17, sizeof(l_uint8));
1922 for (i = 0; i < 17; i++)
1923 tab[i] = 0xff - (i * 255) / 16;
1924 return tab;
1925}
1926
1927
1928/*------------------------------------------------------------------*
1929 * Scale-to-gray 6x *
1930 *------------------------------------------------------------------*/
1964static void
1965scaleToGray6Low(l_uint32 *datad,
1966 l_int32 wd,
1967 l_int32 hd,
1968 l_int32 wpld,
1969 l_uint32 *datas,
1970 l_int32 wpls,
1971 l_int32 *tab8,
1972 l_uint8 *valtab)
1973{
1974l_int32 i, j, l, k;
1975l_uint32 threebytes1, threebytes2, threebytes3;
1976l_uint32 threebytes4, threebytes5, threebytes6, sum;
1977l_uint32 *lines, *lined;
1978
1979 /* i indexes the dest lines
1980 * l indexes the source lines
1981 * j indexes the dest bytes
1982 * k indexes the source bytes
1983 * We take 18 bytes from the source (144 binary pixels
1984 * in six lines of 24 pixels each) and convert it
1985 * into 4 bytes of the dest (four 8 bpp pixels in one line) */
1986 for (i = 0, l = 0; i < hd; i++, l += 6) {
1987 lines = datas + l * wpls;
1988 lined = datad + i * wpld;
1989 for (j = 0, k = 0; j < wd; j += 4, k += 3) {
1990 /* First grab the 18 bytes, 3 at a time, and put each set
1991 * of 3 bytes into the LS bytes of a 32-bit word. */
1992 threebytes1 = (GET_DATA_BYTE(lines, k) << 16) |
1993 (GET_DATA_BYTE(lines, k + 1) << 8) |
1994 GET_DATA_BYTE(lines, k + 2);
1995 threebytes2 = (GET_DATA_BYTE(lines + wpls, k) << 16) |
1996 (GET_DATA_BYTE(lines + wpls, k + 1) << 8) |
1997 GET_DATA_BYTE(lines + wpls, k + 2);
1998 threebytes3 = (GET_DATA_BYTE(lines + 2 * wpls, k) << 16) |
1999 (GET_DATA_BYTE(lines + 2 * wpls, k + 1) << 8) |
2000 GET_DATA_BYTE(lines + 2 * wpls, k + 2);
2001 threebytes4 = (GET_DATA_BYTE(lines + 3 * wpls, k) << 16) |
2002 (GET_DATA_BYTE(lines + 3 * wpls, k + 1) << 8) |
2003 GET_DATA_BYTE(lines + 3 * wpls, k + 2);
2004 threebytes5 = (GET_DATA_BYTE(lines + 4 * wpls, k) << 16) |
2005 (GET_DATA_BYTE(lines + 4 * wpls, k + 1) << 8) |
2006 GET_DATA_BYTE(lines + 4 * wpls, k + 2);
2007 threebytes6 = (GET_DATA_BYTE(lines + 5 * wpls, k) << 16) |
2008 (GET_DATA_BYTE(lines + 5 * wpls, k + 1) << 8) |
2009 GET_DATA_BYTE(lines + 5 * wpls, k + 2);
2010
2011 /* Sum first set of 36 bits and convert to 0-255 */
2012 sum = tab8[(threebytes1 >> 18)] +
2013 tab8[(threebytes2 >> 18)] +
2014 tab8[(threebytes3 >> 18)] +
2015 tab8[(threebytes4 >> 18)] +
2016 tab8[(threebytes5 >> 18)] +
2017 tab8[(threebytes6 >> 18)];
2018 SET_DATA_BYTE(lined, j, valtab[GET_DATA_BYTE(&sum, 3)]);
2019
2020 /* Ditto for second set */
2021 sum = tab8[((threebytes1 >> 12) & 0x3f)] +
2022 tab8[((threebytes2 >> 12) & 0x3f)] +
2023 tab8[((threebytes3 >> 12) & 0x3f)] +
2024 tab8[((threebytes4 >> 12) & 0x3f)] +
2025 tab8[((threebytes5 >> 12) & 0x3f)] +
2026 tab8[((threebytes6 >> 12) & 0x3f)];
2027 SET_DATA_BYTE(lined, j + 1, valtab[GET_DATA_BYTE(&sum, 3)]);
2028
2029 sum = tab8[((threebytes1 >> 6) & 0x3f)] +
2030 tab8[((threebytes2 >> 6) & 0x3f)] +
2031 tab8[((threebytes3 >> 6) & 0x3f)] +
2032 tab8[((threebytes4 >> 6) & 0x3f)] +
2033 tab8[((threebytes5 >> 6) & 0x3f)] +
2034 tab8[((threebytes6 >> 6) & 0x3f)];
2035 SET_DATA_BYTE(lined, j + 2, valtab[GET_DATA_BYTE(&sum, 3)]);
2036
2037 sum = tab8[(threebytes1 & 0x3f)] +
2038 tab8[(threebytes2 & 0x3f)] +
2039 tab8[(threebytes3 & 0x3f)] +
2040 tab8[(threebytes4 & 0x3f)] +
2041 tab8[(threebytes5 & 0x3f)] +
2042 tab8[(threebytes6 & 0x3f)];
2043 SET_DATA_BYTE(lined, j + 3, valtab[GET_DATA_BYTE(&sum, 3)]);
2044 }
2045 }
2046}
2047
2048
2060static l_uint8 *
2062{
2063l_int32 i;
2064l_uint8 *tab;
2065
2066 PROCNAME("makeValTabSG6");
2067
2068 tab = (l_uint8 *)LEPT_CALLOC(37, sizeof(l_uint8));
2069 for (i = 0; i < 37; i++)
2070 tab[i] = 0xff - (i * 255) / 36;
2071 return tab;
2072}
2073
2074
2075/*------------------------------------------------------------------*
2076 * Scale-to-gray 8x *
2077 *------------------------------------------------------------------*/
2102static void
2103scaleToGray8Low(l_uint32 *datad,
2104 l_int32 wd,
2105 l_int32 hd,
2106 l_int32 wpld,
2107 l_uint32 *datas,
2108 l_int32 wpls,
2109 l_int32 *tab8,
2110 l_uint8 *valtab)
2111{
2112l_int32 i, j, k;
2113l_int32 sbyte0, sbyte1, sbyte2, sbyte3, sbyte4, sbyte5, sbyte6, sbyte7, sum;
2114l_uint32 *lines, *lined;
2115
2116 /* i indexes the dest lines
2117 * k indexes the source lines
2118 * j indexes the src and dest bytes
2119 * We take 8 bytes from the source (in 8 lines of 8 pixels
2120 * each) and convert it into one 8 bpp byte of the dest. */
2121 for (i = 0, k = 0; i < hd; i++, k += 8) {
2122 lines = datas + k * wpls;
2123 lined = datad + i * wpld;
2124 for (j = 0; j < wd; j++) {
2125 sbyte0 = GET_DATA_BYTE(lines, j);
2126 sbyte1 = GET_DATA_BYTE(lines + wpls, j);
2127 sbyte2 = GET_DATA_BYTE(lines + 2 * wpls, j);
2128 sbyte3 = GET_DATA_BYTE(lines + 3 * wpls, j);
2129 sbyte4 = GET_DATA_BYTE(lines + 4 * wpls, j);
2130 sbyte5 = GET_DATA_BYTE(lines + 5 * wpls, j);
2131 sbyte6 = GET_DATA_BYTE(lines + 6 * wpls, j);
2132 sbyte7 = GET_DATA_BYTE(lines + 7 * wpls, j);
2133 sum = tab8[sbyte0] + tab8[sbyte1] +
2134 tab8[sbyte2] + tab8[sbyte3] +
2135 tab8[sbyte4] + tab8[sbyte5] +
2136 tab8[sbyte6] + tab8[sbyte7];
2137 SET_DATA_BYTE(lined, j, valtab[sum]);
2138 }
2139 }
2140}
2141
2142
2154static l_uint8 *
2156{
2157l_int32 i;
2158l_uint8 *tab;
2159
2160 PROCNAME("makeValTabSG8");
2161
2162 tab = (l_uint8 *)LEPT_CALLOC(65, sizeof(l_uint8));
2163 for (i = 0; i < 65; i++)
2164 tab[i] = 0xff - (i * 255) / 64;
2165 return tab;
2166}
2167
2168
2169/*------------------------------------------------------------------*
2170 * Scale-to-gray 16x *
2171 *------------------------------------------------------------------*/
2194static void
2195scaleToGray16Low(l_uint32 *datad,
2196 l_int32 wd,
2197 l_int32 hd,
2198 l_int32 wpld,
2199 l_uint32 *datas,
2200 l_int32 wpls,
2201 l_int32 *tab8)
2202{
2203l_int32 i, j, k, m;
2204l_int32 sum;
2205l_uint32 *lines, *lined;
2206
2207 /* i indexes the dest lines
2208 * k indexes the source lines
2209 * j indexes the dest bytes
2210 * m indexes the src bytes
2211 * We take 32 bytes from the source (in 16 lines of 16 pixels
2212 * each) and convert it into one 8 bpp byte of the dest. */
2213 for (i = 0, k = 0; i < hd; i++, k += 16) {
2214 lines = datas + k * wpls;
2215 lined = datad + i * wpld;
2216 for (j = 0; j < wd; j++) {
2217 m = 2 * j;
2218 sum = tab8[GET_DATA_BYTE(lines, m)];
2219 sum += tab8[GET_DATA_BYTE(lines, m + 1)];
2220 sum += tab8[GET_DATA_BYTE(lines + wpls, m)];
2221 sum += tab8[GET_DATA_BYTE(lines + wpls, m + 1)];
2222 sum += tab8[GET_DATA_BYTE(lines + 2 * wpls, m)];
2223 sum += tab8[GET_DATA_BYTE(lines + 2 * wpls, m + 1)];
2224 sum += tab8[GET_DATA_BYTE(lines + 3 * wpls, m)];
2225 sum += tab8[GET_DATA_BYTE(lines + 3 * wpls, m + 1)];
2226 sum += tab8[GET_DATA_BYTE(lines + 4 * wpls, m)];
2227 sum += tab8[GET_DATA_BYTE(lines + 4 * wpls, m + 1)];
2228 sum += tab8[GET_DATA_BYTE(lines + 5 * wpls, m)];
2229 sum += tab8[GET_DATA_BYTE(lines + 5 * wpls, m + 1)];
2230 sum += tab8[GET_DATA_BYTE(lines + 6 * wpls, m)];
2231 sum += tab8[GET_DATA_BYTE(lines + 6 * wpls, m + 1)];
2232 sum += tab8[GET_DATA_BYTE(lines + 7 * wpls, m)];
2233 sum += tab8[GET_DATA_BYTE(lines + 7 * wpls, m + 1)];
2234 sum += tab8[GET_DATA_BYTE(lines + 8 * wpls, m)];
2235 sum += tab8[GET_DATA_BYTE(lines + 8 * wpls, m + 1)];
2236 sum += tab8[GET_DATA_BYTE(lines + 9 * wpls, m)];
2237 sum += tab8[GET_DATA_BYTE(lines + 9 * wpls, m + 1)];
2238 sum += tab8[GET_DATA_BYTE(lines + 10 * wpls, m)];
2239 sum += tab8[GET_DATA_BYTE(lines + 10 * wpls, m + 1)];
2240 sum += tab8[GET_DATA_BYTE(lines + 11 * wpls, m)];
2241 sum += tab8[GET_DATA_BYTE(lines + 11 * wpls, m + 1)];
2242 sum += tab8[GET_DATA_BYTE(lines + 12 * wpls, m)];
2243 sum += tab8[GET_DATA_BYTE(lines + 12 * wpls, m + 1)];
2244 sum += tab8[GET_DATA_BYTE(lines + 13 * wpls, m)];
2245 sum += tab8[GET_DATA_BYTE(lines + 13 * wpls, m + 1)];
2246 sum += tab8[GET_DATA_BYTE(lines + 14 * wpls, m)];
2247 sum += tab8[GET_DATA_BYTE(lines + 14 * wpls, m + 1)];
2248 sum += tab8[GET_DATA_BYTE(lines + 15 * wpls, m)];
2249 sum += tab8[GET_DATA_BYTE(lines + 15 * wpls, m + 1)];
2250 sum = L_MIN(sum, 255);
2251 SET_DATA_BYTE(lined, j, 255 - sum);
2252 }
2253 }
2254}
2255
2256
2257
2258/*------------------------------------------------------------------*
2259 * Grayscale mipmap *
2260 *------------------------------------------------------------------*/
2271static l_int32
2272scaleMipmapLow(l_uint32 *datad,
2273 l_int32 wd,
2274 l_int32 hd,
2275 l_int32 wpld,
2276 l_uint32 *datas1,
2277 l_int32 wpls1,
2278 l_uint32 *datas2,
2279 l_int32 wpls2,
2280 l_float32 red)
2281{
2282l_int32 i, j, val1, val2, val, row2, col2;
2283l_int32 *srow, *scol;
2284l_uint32 *lines1, *lines2, *lined;
2285l_float32 ratio, w1, w2;
2286
2287 PROCNAME("scaleMipmapLow");
2288
2289 /* Clear dest */
2290 memset(datad, 0, 4LL * wpld * hd);
2291
2292 /* Each dest pixel at (j,i) is computed by interpolating
2293 between the two src images at the corresponding location.
2294 We store the UL corner locations of the square of
2295 src pixels in thelower-resolution image that correspond
2296 to dest pixel (j,i). The are labeled by the arrays
2297 srow[i], scol[j]. The UL corner locations of the higher
2298 resolution src pixels are obtained from these arrays
2299 by multiplying by 2. */
2300 if ((srow = (l_int32 *)LEPT_CALLOC(hd, sizeof(l_int32))) == NULL)
2301 return ERROR_INT("srow not made", procName, 1);
2302 if ((scol = (l_int32 *)LEPT_CALLOC(wd, sizeof(l_int32))) == NULL) {
2303 LEPT_FREE(srow);
2304 return ERROR_INT("scol not made", procName, 1);
2305 }
2306 ratio = 1. / (2. * red); /* 0.5 for red = 1, 1 for red = 0.5 */
2307 for (i = 0; i < hd; i++)
2308 srow[i] = (l_int32)(ratio * i);
2309 for (j = 0; j < wd; j++)
2310 scol[j] = (l_int32)(ratio * j);
2311
2312 /* Get weights for linear interpolation: these are the
2313 * 'distances' of the dest image plane from the two
2314 * src image planes. */
2315 w1 = 2. * red - 1.; /* w1 --> 1 as red --> 1 */
2316 w2 = 1. - w1;
2317
2318 /* For each dest pixel, compute linear interpolation */
2319 for (i = 0; i < hd; i++) {
2320 row2 = srow[i];
2321 lines1 = datas1 + 2 * row2 * wpls1;
2322 lines2 = datas2 + row2 * wpls2;
2323 lined = datad + i * wpld;
2324 for (j = 0; j < wd; j++) {
2325 col2 = scol[j];
2326 val1 = GET_DATA_BYTE(lines1, 2 * col2);
2327 val2 = GET_DATA_BYTE(lines2, col2);
2328 val = (l_int32)(w1 * val1 + w2 * val2);
2329 SET_DATA_BYTE(lined, j, val);
2330 }
2331 }
2332
2333 LEPT_FREE(srow);
2334 LEPT_FREE(scol);
2335 return 0;
2336}
#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
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
l_ok pixCopyColormap(PIX *pixd, const PIX *pixs)
pixCopyColormap()
Definition: pix1.c:816
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok pixSetBorderRingVal(PIX *pixs, l_int32 dist, l_uint32 val)
pixSetBorderRingVal()
Definition: pix2.c:1667
l_ok pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition: pix2.c:2690
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:817
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1382
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition: pix2.c:2479
l_ok pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition: pix2.c:2538
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:951
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2411
PIX * pixResizeToMatch(PIX *pixs, PIX *pixt, l_int32 w, l_int32 h)
pixResizeToMatch()
Definition: pix5.c:1321
@ L_ALPHA_CHANNEL
Definition: pix.h:207
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2401
PIX * pixScaleBinary(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBinary()
Definition: scale1.c:2161
PIX * pixScaleSmooth(PIX *pix, l_float32 scalex, l_float32 scaley)
pixScaleSmooth()
Definition: scale1.c:1709
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:780
PIX * pixScaleGeneral(PIX *pixs, l_float32 scalex, l_float32 scaley, l_float32 sharpfract, l_int32 sharpwidth)
pixScaleGeneral()
Definition: scale1.c:423
static l_uint8 * makeValTabSG3(void)
makeValTabSG3()
Definition: scale2.c:1793
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:2195
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:1965
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:1836
l_ok pixScaleAndTransferAlpha(PIX *pixd, PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleAndTransferAlpha()
Definition: scale2.c:1364
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:1545
static l_uint32 * makeSumTabSG2(void)
makeSumTabSG2()
Definition: scale2.c:1605
PIX * pixScaleGrayRank2(PIX *pixs, l_int32 rank)
pixScaleGrayRank2()
Definition: scale2.c:1273
PIX * pixScaleGrayMinMax2(PIX *pixs, l_int32 type)
pixScaleGrayMinMax2()
Definition: scale2.c:1126
PIX * pixScaleToGray3(PIX *pixs)
pixScaleToGray3()
Definition: scale2.c:448
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:2103
static l_uint8 * makeValTabSG2(void)
makeValTabSG2()
Definition: scale2.c:1635
PIX * pixScaleToGray(PIX *pixs, l_float32 scalefactor)
pixScaleToGray()
Definition: scale2.c:208
static l_uint32 * makeSumTabSG3(void)
makeSumTabSG3()
Definition: scale2.c:1764
PIX * pixScaleToGray8(PIX *pixs)
pixScaleToGray8()
Definition: scale2.c:605
PIX * pixScaleMipmap(PIX *pixs1, PIX *pixs2, l_float32 scale)
pixScaleMipmap()
Definition: scale2.c:815
PIX * pixScaleGrayMinMax(PIX *pixs, l_int32 xfact, l_int32 yfact, l_int32 type)
pixScaleGrayMinMax()
Definition: scale2.c:1019
PIX * pixScaleToGray6(PIX *pixs)
pixScaleToGray6()
Definition: scale2.c:557
static l_uint8 * makeValTabSG4(void)
makeValTabSG4()
Definition: scale2.c:1914
PIX * pixExpandReplicate(PIX *pixs, l_int32 factor)
pixExpandReplicate()
Definition: scale2.c:872
static l_uint8 * makeValTabSG6(void)
makeValTabSG6()
Definition: scale2.c:2061
PIX * pixScaleToGrayFast(PIX *pixs, l_float32 scalefactor)
pixScaleToGrayFast()
Definition: scale2.c:319
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:1687
PIX * pixScaleToGray4(PIX *pixs)
pixScaleToGray4()
Definition: scale2.c:502
PIX * pixScaleToGrayMipmap(PIX *pixs, l_float32 scalefactor)
pixScaleToGrayMipmap()
Definition: scale2.c:727
PIX * pixScaleToGray2(PIX *pixs)
pixScaleToGray2()
Definition: scale2.c:390
PIX * pixScaleToGray16(PIX *pixs)
pixScaleToGray16()
Definition: scale2.c:654
PIX * pixScaleGrayRankCascade(PIX *pixs, l_int32 level1, l_int32 level2, l_int32 level3, l_int32 level4)
pixScaleGrayRankCascade()
Definition: scale2.c:1209
static l_uint8 * makeValTabSG8(void)
makeValTabSG8()
Definition: scale2.c:2155
static l_uint32 * makeSumTabSG4(void)
makeSumTabSG4()
Definition: scale2.c:1885
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:2272
PIX * pixScaleWithAlpha(PIX *pixs, l_float32 scalex, l_float32 scaley, PIX *pixg, l_float32 fract)
pixScaleWithAlpha()
Definition: scale2.c:1443
Definition: pix.h:139
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306