Leptonica 1.68
C Image Processing Library

rotateorth.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 /*
00018  *  rotateorth.c
00019  *
00020  *      Top-level rotation by multiples of 90 degrees
00021  *            PIX     *pixRotateOrth()
00022  *
00023  *      180-degree rotation
00024  *            PIX     *pixRotate180()
00025  *
00026  *      90-degree rotation (both directions)
00027  *            PIX     *pixRotate90()
00028  *
00029  *      Left-right flip
00030  *            PIX     *pixFlipLR()
00031  *
00032  *      Top-bottom flip
00033  *            PIX     *pixFlipTB()
00034  */
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include "allheaders.h"
00039 
00040 
00041 /*!
00042  *  pixRotateOrth()
00043  *
00044  *      Input:  pixs (all depths)
00045  *              quads (0-3; number of 90 degree cw rotations)
00046  *      Return: pixd, or null on error
00047  */
00048 PIX *
00049 pixRotateOrth(PIX     *pixs,
00050               l_int32  quads)
00051 {
00052     PROCNAME("pixRotateOrth");
00053 
00054     if (!pixs)
00055         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00056     if (quads < 0 || quads > 4)
00057         return (PIX *)ERROR_PTR("quads not in {0,1,2,3,4}", procName, NULL);
00058 
00059     if (quads == 0 || quads == 4)
00060         return pixCopy(NULL, pixs);
00061     else if (quads == 1)
00062         return pixRotate90(pixs, 1);
00063     else if (quads == 2)
00064         return pixRotate180(NULL, pixs);
00065     else /* quads == 3 */
00066         return pixRotate90(pixs, -1);
00067 }
00068     
00069 
00070 /*!
00071  *  pixRotate180()
00072  *
00073  *      Input:  pixd  (<optional>; can be null, equal to pixs,
00074  *                     or different from pixs)
00075  *              pixs (all depths)
00076  *      Return: pixd, or null on error
00077  *
00078  *  Notes:
00079  *      (1) This does a 180 rotation of the image about the center,
00080  *          which is equivalent to a left-right flip about a vertical
00081  *          line through the image center, followed by a top-bottom
00082  *          flip about a horizontal line through the image center.
00083  *      (2) There are 3 cases for input:
00084  *          (a) pixd == null (creates a new pixd)
00085  *          (b) pixd == pixs (in-place operation)
00086  *          (c) pixd != pixs (existing pixd)
00087  *      (3) For clarity, use these three patterns, respectively:
00088  *          (a) pixd = pixRotate180(NULL, pixs);
00089  *          (b) pixRotate180(pixs, pixs);
00090  *          (c) pixRotate180(pixd, pixs);
00091  */
00092 PIX *
00093 pixRotate180(PIX  *pixd,
00094              PIX  *pixs)
00095 {
00096 l_int32  d;
00097 
00098     PROCNAME("pixRotate180");
00099 
00100     if (!pixs)
00101         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00102     d = pixGetDepth(pixs);
00103     if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
00104         return (PIX *)ERROR_PTR("pixs not in {1,2,4,8,16,32} bpp",
00105                                 procName, NULL);
00106 
00107         /* Prepare pixd for in-place operation */
00108     if ((pixd = pixCopy(pixd, pixs)) == NULL)
00109         return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00110 
00111     pixFlipLR(pixd, pixd);
00112     pixFlipTB(pixd, pixd);
00113     return pixd;
00114 }
00115     
00116 
00117 /*!
00118  *  pixRotate90()
00119  *
00120  *      Input:  pixs (all depths)
00121  *              direction (1 = clockwise,  -1 = counter-clockwise)
00122  *      Return: pixd, or null on error
00123  *
00124  *  Notes:
00125  *      (1) This does a 90 degree rotation of the image about the center,
00126  *          either cw or ccw, returning a new pix.
00127  *      (2) The direction must be either 1 (cw) or -1 (ccw).
00128  */
00129 PIX *
00130 pixRotate90(PIX     *pixs,
00131             l_int32  direction)
00132 {
00133 l_int32    wd, hd, d, wpls, wpld;
00134 l_uint32  *datas, *datad;
00135 PIX       *pixd;
00136 
00137     PROCNAME("pixRotate90");
00138 
00139     if (!pixs)
00140         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00141     d = pixGetDepth(pixs);
00142     if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
00143         return (PIX *)ERROR_PTR("pixs not in {1,2,4,8,16,32} bpp",
00144                                 procName, NULL);
00145     if (direction != 1 && direction != -1)
00146         return (PIX *)ERROR_PTR("invalid direction", procName, NULL);
00147 
00148     hd = pixGetWidth(pixs);
00149     wd = pixGetHeight(pixs);
00150     if ((pixd = pixCreate(wd, hd, d)) == NULL)
00151         return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00152     pixCopyColormap(pixd, pixs);
00153     pixCopyResolution(pixd, pixs);
00154     pixCopyInputFormat(pixd, pixs);
00155 
00156     datas = pixGetData(pixs);
00157     wpls = pixGetWpl(pixs);
00158     datad = pixGetData(pixd);
00159     wpld = pixGetWpl(pixd);
00160 
00161     rotate90Low(datad, wd, hd, d, wpld, datas, wpls, direction);
00162 
00163     return pixd;
00164 }
00165 
00166 
00167 /*!
00168  *  pixFlipLR()
00169  *
00170  *      Input:  pixd  (<optional>; can be null, equal to pixs,
00171  *                     or different from pixs)
00172  *              pixs (all depths)
00173  *      Return: pixd, or null on error
00174  *
00175  *  Notes:
00176  *      (1) This does a left-right flip of the image, which is
00177  *          equivalent to a rotation out of the plane about a
00178  *          vertical line through the image center.
00179  *      (2) There are 3 cases for input:
00180  *          (a) pixd == null (creates a new pixd)
00181  *          (b) pixd == pixs (in-place operation)
00182  *          (c) pixd != pixs (existing pixd)
00183  *      (3) For clarity, use these three patterns, respectively:
00184  *          (a) pixd = pixFlipLR(NULL, pixs);
00185  *          (b) pixFlipLR(pixs, pixs);
00186  *          (c) pixFlipLR(pixd, pixs);
00187  *      (4) If an existing pixd is not the same size as pixs, the
00188  *          image data will be reallocated.
00189  */
00190 PIX *
00191 pixFlipLR(PIX  *pixd,
00192           PIX  *pixs)
00193 {
00194 l_uint8   *tab;
00195 l_int32    w, h, d, wpld;
00196 l_uint32  *datad, *buffer;
00197 
00198     PROCNAME("pixFlipLR");
00199 
00200     if (!pixs)
00201         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00202     pixGetDimensions(pixs, &w, &h, &d);
00203     if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
00204         return (PIX *)ERROR_PTR("pixs not in {1,2,4,8,16,32} bpp",
00205                                 procName, NULL);
00206 
00207         /* Prepare pixd for in-place operation */
00208     if ((pixd = pixCopy(pixd, pixs)) == NULL)
00209         return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00210 
00211     datad = pixGetData(pixd);
00212     wpld = pixGetWpl(pixd);
00213     switch (d)
00214     {
00215     case 1:
00216         tab = makeReverseByteTab1();
00217         break;
00218     case 2:
00219         tab = makeReverseByteTab2();
00220         break;
00221     case 4:
00222         tab = makeReverseByteTab4();
00223         break;
00224     default:
00225         tab = NULL;
00226         break;
00227     }
00228 
00229     if ((buffer = (l_uint32 *)CALLOC(wpld, sizeof(l_uint32))) == NULL)
00230         return (PIX *)ERROR_PTR("buffer not made", procName, NULL);
00231 
00232     flipLRLow(datad, w, h, d, wpld, tab, buffer);
00233 
00234     FREE(buffer);
00235     if (tab) FREE(tab);
00236     return pixd;
00237 }
00238 
00239 
00240 /*!
00241  *  pixFlipTB()
00242  *
00243  *      Input:  pixd  (<optional>; can be null, equal to pixs,
00244  *                     or different from pixs)
00245  *              pixs (all depths)
00246  *      Return: pixd, or null on error
00247  *
00248  *  Notes:
00249  *      (1) This does a top-bottom flip of the image, which is
00250  *          equivalent to a rotation out of the plane about a
00251  *          horizontal line through the image center.
00252  *      (2) There are 3 cases for input:
00253  *          (a) pixd == null (creates a new pixd)
00254  *          (b) pixd == pixs (in-place operation)
00255  *          (c) pixd != pixs (existing pixd)
00256  *      (3) For clarity, use these three patterns, respectively:
00257  *          (a) pixd = pixFlipTB(NULL, pixs);
00258  *          (b) pixFlipTB(pixs, pixs);
00259  *          (c) pixFlipTB(pixd, pixs);
00260  *      (4) If an existing pixd is not the same size as pixs, the
00261  *          image data will be reallocated.
00262  */
00263 PIX *
00264 pixFlipTB(PIX  *pixd,
00265           PIX  *pixs)
00266 {
00267 l_int32    h, d, wpld;
00268 l_uint32  *datad, *buffer;
00269 
00270     PROCNAME("pixFlipTB");
00271 
00272     if (!pixs)
00273         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00274     pixGetDimensions(pixs, NULL, &h, &d);
00275     if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
00276         return (PIX *)ERROR_PTR("pixs not in {1,2,4,8,16,32} bpp",
00277                                 procName, NULL);
00278 
00279         /* Prepare pixd for in-place operation */
00280     if ((pixd = pixCopy(pixd, pixs)) == NULL)
00281         return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00282 
00283     datad = pixGetData(pixd);
00284     wpld = pixGetWpl(pixd);
00285     if ((buffer = (l_uint32 *)CALLOC(wpld, sizeof(l_uint32))) == NULL)
00286         return (PIX *)ERROR_PTR("buffer not made", procName, NULL);
00287 
00288     flipTBLow(datad, h, wpld, buffer);
00289 
00290     FREE(buffer);
00291     return pixd;
00292 }
00293 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines