Leptonica 1.68
C Image Processing Library

subpixel_reg.c

Go to the documentation of this file.
00001 /*====================================================================*
00002  -  Copyright (C) 2001 Leptonica.  All rights reserved.
00003  -  This software is distributed in the hope that it will be
00004  -  useful, but with NO WARRANTY OF ANY KIND.
00005  -  No author or distributor accepts responsibility to anyone for the
00006  -  consequences of using this software, or for whether it serves any
00007  -  particular purpose or works at all, unless he or she says so in
00008  -  writing.  Everyone is granted permission to copy, modify and
00009  -  redistribute this source code, for commercial or non-commercial
00010  -  purposes, with the following restrictions: (1) the origin of this
00011  -  source code must not be misrepresented; (2) modified versions must
00012  -  be plainly marked as such; and (3) this notice may not be removed
00013  -  or altered from any source or modified source distribution.
00014  *====================================================================*/
00015 
00016 /*
00017  * subpixel_reg.c
00018  *
00019  *   Regression test for subpixel scaling.
00020  */
00021 
00022 #include "allheaders.h"
00023 
00024 void AddTextAndSave(PIXA *pixa, PIX *pixs, l_int32 newrow,
00025                     L_BMF *bmf, const char *textstr,
00026                     l_int32 location, l_uint32 val);
00027 
00028 const char  *textstr[] =
00029            {"Downscaled with sharpening",
00030             "Subpixel scaling; horiz R-G-B",
00031             "Subpixel scaling; horiz B-G-R",
00032             "Subpixel scaling; vert R-G-B",
00033             "Subpixel scaling; vert B-G-R"};
00034 
00035 main(int    argc,
00036      char **argv)
00037 {
00038 l_float32     scalefact;
00039 L_BMF        *bmf, *bmftop;
00040 L_KERNEL     *kel, *kelx, *kely;
00041 PIX          *pixs, *pixg, *pixt, *pixd;
00042 PIX          *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pix8;
00043 PIXA         *pixa;
00044 L_REGPARAMS  *rp;
00045 
00046     if (regTestSetup(argc, argv, &rp))
00047         return 1;
00048 
00049     /* ----------------- Test on 8 bpp grayscale ---------------------*/
00050     pixa = pixaCreate(5);
00051     bmf = bmfCreate("./fonts", 6);
00052     bmftop = bmfCreate("./fonts", 10);
00053     pixs = pixRead("lucasta-47.jpg");
00054     pixg = pixScale(pixs, 0.4, 0.4);  /* 8 bpp grayscale */
00055     pix1 = pixConvertTo32(pixg);  /* 32 bpp rgb */
00056     AddTextAndSave(pixa, pix1, 1, bmf, textstr[0], L_ADD_BELOW, 0xff000000);
00057     pix2 = pixConvertGrayToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_RGB);
00058     AddTextAndSave(pixa, pix2, 0, bmf, textstr[1], L_ADD_BELOW, 0x00ff0000);
00059     pix3 = pixConvertGrayToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_BGR);
00060     AddTextAndSave(pixa, pix3, 0, bmf, textstr[2], L_ADD_BELOW, 0x0000ff00);
00061     pix4 = pixConvertGrayToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_VRGB);
00062     AddTextAndSave(pixa, pix4, 0, bmf, textstr[3], L_ADD_BELOW, 0x00ff0000);
00063     pix5 = pixConvertGrayToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_VBGR);
00064     AddTextAndSave(pixa, pix5, 0, bmf, textstr[4], L_ADD_BELOW, 0x0000ff00);
00065 
00066     pixt = pixaDisplay(pixa, 0, 0);
00067     pixd = pixAddSingleTextblock(pixt, bmftop,
00068                                  "Regression test for subpixel scaling: gray",
00069                                  0xff00ff00, L_ADD_ABOVE, NULL);
00070     regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG);  /* 0 */
00071     pixDisplayWithTitle(pixd, 50, 50, NULL, rp->display);
00072     pixaDestroy(&pixa);
00073     pixDestroy(&pixs);
00074     pixDestroy(&pixg);
00075     pixDestroy(&pixt);
00076     pixDestroy(&pixd);
00077     pixDestroy(&pix1);
00078     pixDestroy(&pix2);
00079     pixDestroy(&pix3);
00080     pixDestroy(&pix4);
00081     pixDestroy(&pix5);
00082 
00083 
00084     /* ----------------- Test on 32 bpp rgb ---------------------*/
00085     pixa = pixaCreate(5);
00086     pixs = pixRead("fish24.jpg");
00087     pix1 = pixScale(pixs, 0.4, 0.4);
00088     AddTextAndSave(pixa, pix1, 1, bmf, textstr[0], L_ADD_BELOW, 0xff000000);
00089     pix2 = pixConvertToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_RGB);
00090     AddTextAndSave(pixa, pix2, 0, bmf, textstr[1], L_ADD_BELOW, 0x00ff0000);
00091     pix3 = pixConvertToSubpixelRGB(pixs, 0.4, 0.35, L_SUBPIXEL_ORDER_BGR);
00092     AddTextAndSave(pixa, pix3, 0, bmf, textstr[2], L_ADD_BELOW, 0x0000ff00);
00093     pix4 = pixConvertToSubpixelRGB(pixs, 0.4, 0.45, L_SUBPIXEL_ORDER_VRGB);
00094     AddTextAndSave(pixa, pix4, 0, bmf, textstr[3], L_ADD_BELOW, 0x00ff0000);
00095     pix5 = pixConvertToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_VBGR);
00096     AddTextAndSave(pixa, pix5, 0, bmf, textstr[4], L_ADD_BELOW, 0x0000ff00);
00097 
00098     pixt = pixaDisplay(pixa, 0, 0);
00099     pixd = pixAddSingleTextblock(pixt, bmftop,
00100                                  "Regression test for subpixel scaling: color",
00101                                  0xff00ff00, L_ADD_ABOVE, NULL);
00102     regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG);  /* 1 */
00103     pixDisplayWithTitle(pixd, 50, 350, NULL, rp->display);
00104     pixaDestroy(&pixa);
00105     pixDestroy(&pixs);
00106     pixDestroy(&pixt);
00107     pixDestroy(&pixd);
00108     pixDestroy(&pix1);
00109     pixDestroy(&pix2);
00110     pixDestroy(&pix3);
00111     pixDestroy(&pix4);
00112     pixDestroy(&pix5);
00113     bmfDestroy(&bmf);
00114     bmfDestroy(&bmftop);
00115 
00116 
00117     /* --------------- Test on images that are initially 1 bpp ------------*/
00118     /*   For these, it is better to apply a lowpass filter before scaling  */
00119         /* Normal scaling of 8 bpp grayscale */
00120     scalefact = 800. / 2320.;
00121     pixs = pixRead("patent.png");   /* sharp, 300 ppi, 1 bpp image */
00122     pix1 = pixConvertTo8(pixs, FALSE);  /* use 8 bpp input */
00123     pix2 = pixScale(pix1, scalefact, scalefact);
00124     regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 2 */
00125 
00126         /* Subpixel scaling; bad because there is very little aliasing. */
00127     pix3 = pixConvertToSubpixelRGB(pix1, scalefact, scalefact,
00128                                    L_SUBPIXEL_ORDER_RGB);
00129     regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 3 */
00130 
00131        /* Get same (bad) result doing subpixel rendering on RGB input */
00132     pix4 = pixConvertTo32(pixs);
00133     pix5 = pixConvertToSubpixelRGB(pix4, scalefact, scalefact,
00134                                    L_SUBPIXEL_ORDER_RGB);
00135     regTestComparePix(rp, pix3, pix5);  /* 4 */
00136     regTestWritePixAndCheck(rp, pix5, IFF_PNG);  /* 5 */
00137 
00138         /* Now apply a small lowpass filter before scaling. */
00139     makeGaussianKernelSep(2, 2, 1.0, 1.0, &kelx, &kely);
00140     startTimer();
00141     pix6 = pixConvolveSep(pix1, kelx, kely, 8, 1);  /* normalized */
00142     fprintf(stderr, "Time sep: %7.3f\n", stopTimer());
00143     regTestWritePixAndCheck(rp, pix6, IFF_PNG);  /* 6 */
00144 
00145         /* Get same lowpass result with non-separated convolution */
00146     kel = makeGaussianKernel(2, 2, 1.0, 1.0);
00147     startTimer();
00148     pix7 = pixConvolve(pix1, kel, 8, 1);  /* normalized */
00149     fprintf(stderr, "Time non-sep: %7.3f\n", stopTimer());
00150     regTestComparePix(rp, pix6, pix7);  /* 7 */
00151 
00152         /* Now do the subpixel scaling on this slightly blurred image */
00153     pix8 = pixConvertToSubpixelRGB(pix6, scalefact, scalefact,
00154                                    L_SUBPIXEL_ORDER_RGB);
00155     regTestWritePixAndCheck(rp, pix8, IFF_PNG);  /* 8 */
00156 
00157     kernelDestroy(&kelx);
00158     kernelDestroy(&kely);
00159     kernelDestroy(&kel);
00160     pixDestroy(&pixs);
00161     pixDestroy(&pix1);
00162     pixDestroy(&pix2);
00163     pixDestroy(&pix3);
00164     pixDestroy(&pix4);
00165     pixDestroy(&pix5);
00166     pixDestroy(&pix6);
00167     pixDestroy(&pix7);
00168     pixDestroy(&pix8);
00169     regTestCleanup(rp);
00170     return 0;
00171 }
00172 
00173 
00174 void
00175 AddTextAndSave(PIXA        *pixa,
00176                PIX         *pixs,
00177                l_int32      newrow,
00178                L_BMF       *bmf,
00179                const char  *textstr,
00180                l_int32      location,
00181                l_uint32     val)
00182 {
00183 l_int32  n, ovf;
00184 PIX     *pixt;
00185 
00186     pixt = pixAddSingleTextblock(pixs, bmf, textstr, val, location, &ovf);
00187     n = pixaGetCount(pixa);
00188     pixSaveTiledOutline(pixt, pixa, 1, newrow, 30, 2, 32);
00189     if (ovf) fprintf(stderr, "Overflow writing text in image %d\n", n + 1);
00190     pixDestroy(&pixt);
00191     return;
00192 }
00193 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines