Leptonica 1.68
C Image Processing Library
|
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