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 * rotateamlow.c 00019 * 00020 * Grayscale and color rotation (area mapped) 00021 * 00022 * 32 bpp grayscale rotation about image center 00023 * void rotateAMColorLow() 00024 * 00025 * 8 bpp grayscale rotation about image center 00026 * void rotateAMGrayLow() 00027 * 00028 * 32 bpp grayscale rotation about UL corner of image 00029 * void rotateAMColorCornerLow() 00030 * 00031 * 8 bpp grayscale rotation about UL corner of image 00032 * void rotateAMGrayCornerLow() 00033 * 00034 * Fast RGB color rotation about center: 00035 * void rotateAMColorFastLow() 00036 * 00037 */ 00038 00039 #include <stdio.h> 00040 #include <string.h> 00041 #include <math.h> /* required for sin and tan */ 00042 #include "allheaders.h" 00043 00044 00045 /*------------------------------------------------------------------* 00046 * 32 bpp grayscale rotation about the center * 00047 *------------------------------------------------------------------*/ 00048 void 00049 rotateAMColorLow(l_uint32 *datad, 00050 l_int32 w, 00051 l_int32 h, 00052 l_int32 wpld, 00053 l_uint32 *datas, 00054 l_int32 wpls, 00055 l_float32 angle, 00056 l_uint32 colorval) 00057 { 00058 l_int32 i, j, xcen, ycen, wm2, hm2; 00059 l_int32 xdif, ydif, xpm, ypm, xp, yp, xf, yf; 00060 l_int32 rval, gval, bval; 00061 l_uint32 word00, word01, word10, word11; 00062 l_uint32 *lines, *lined; 00063 l_float32 sina, cosa; 00064 00065 xcen = w / 2; 00066 wm2 = w - 2; 00067 ycen = h / 2; 00068 hm2 = h - 2; 00069 sina = 16. * sin(angle); 00070 cosa = 16. * cos(angle); 00071 00072 for (i = 0; i < h; i++) { 00073 ydif = ycen - i; 00074 lined = datad + i * wpld; 00075 for (j = 0; j < w; j++) { 00076 xdif = xcen - j; 00077 xpm = (l_int32)(-xdif * cosa - ydif * sina); 00078 ypm = (l_int32)(-ydif * cosa + xdif * sina); 00079 xp = xcen + (xpm >> 4); 00080 yp = ycen + (ypm >> 4); 00081 xf = xpm & 0x0f; 00082 yf = ypm & 0x0f; 00083 00084 /* if off the edge, write input colorval */ 00085 if (xp < 0 || yp < 0 || xp > wm2 || yp > hm2) { 00086 *(lined + j) = colorval; 00087 continue; 00088 } 00089 00090 lines = datas + yp * wpls; 00091 00092 /* do area weighting. Without this, we would 00093 * simply do: 00094 * *(lined + j) = *(lines + xp); 00095 * which is faster but gives lousy results! 00096 */ 00097 word00 = *(lines + xp); 00098 word10 = *(lines + xp + 1); 00099 word01 = *(lines + wpls + xp); 00100 word11 = *(lines + wpls + xp + 1); 00101 rval = ((16 - xf) * (16 - yf) * ((word00 >> L_RED_SHIFT) & 0xff) + 00102 xf * (16 - yf) * ((word10 >> L_RED_SHIFT) & 0xff) + 00103 (16 - xf) * yf * ((word01 >> L_RED_SHIFT) & 0xff) + 00104 xf * yf * ((word11 >> L_RED_SHIFT) & 0xff) + 128) / 256; 00105 gval = ((16 - xf) * (16 - yf) * ((word00 >> L_GREEN_SHIFT) & 0xff) + 00106 xf * (16 - yf) * ((word10 >> L_GREEN_SHIFT) & 0xff) + 00107 (16 - xf) * yf * ((word01 >> L_GREEN_SHIFT) & 0xff) + 00108 xf * yf * ((word11 >> L_GREEN_SHIFT) & 0xff) + 128) / 256; 00109 bval = ((16 - xf) * (16 - yf) * ((word00 >> L_BLUE_SHIFT) & 0xff) + 00110 xf * (16 - yf) * ((word10 >> L_BLUE_SHIFT) & 0xff) + 00111 (16 - xf) * yf * ((word01 >> L_BLUE_SHIFT) & 0xff) + 00112 xf * yf * ((word11 >> L_BLUE_SHIFT) & 0xff) + 128) / 256; 00113 composeRGBPixel(rval, gval, bval, lined + j); 00114 } 00115 } 00116 00117 return; 00118 } 00119 00120 00121 /*------------------------------------------------------------------* 00122 * 8 bpp grayscale rotation about the center * 00123 *------------------------------------------------------------------*/ 00124 void 00125 rotateAMGrayLow(l_uint32 *datad, 00126 l_int32 w, 00127 l_int32 h, 00128 l_int32 wpld, 00129 l_uint32 *datas, 00130 l_int32 wpls, 00131 l_float32 angle, 00132 l_uint8 grayval) 00133 { 00134 l_int32 i, j, xcen, ycen, wm2, hm2; 00135 l_int32 xdif, ydif, xpm, ypm, xp, yp, xf, yf; 00136 l_int32 v00, v01, v10, v11; 00137 l_uint8 val; 00138 l_uint32 *lines, *lined; 00139 l_float32 sina, cosa; 00140 00141 xcen = w / 2; 00142 wm2 = w - 2; 00143 ycen = h / 2; 00144 hm2 = h - 2; 00145 sina = 16. * sin(angle); 00146 cosa = 16. * cos(angle); 00147 00148 for (i = 0; i < h; i++) { 00149 ydif = ycen - i; 00150 lined = datad + i * wpld; 00151 for (j = 0; j < w; j++) { 00152 xdif = xcen - j; 00153 xpm = (l_int32)(-xdif * cosa - ydif * sina); 00154 ypm = (l_int32)(-ydif * cosa + xdif * sina); 00155 xp = xcen + (xpm >> 4); 00156 yp = ycen + (ypm >> 4); 00157 xf = xpm & 0x0f; 00158 yf = ypm & 0x0f; 00159 00160 /* if off the edge, write input grayval */ 00161 if (xp < 0 || yp < 0 || xp > wm2 || yp > hm2) { 00162 SET_DATA_BYTE(lined, j, grayval); 00163 continue; 00164 } 00165 00166 lines = datas + yp * wpls; 00167 00168 /* do area weighting. Without this, we would 00169 * simply do: 00170 * SET_DATA_BYTE(lined, j, GET_DATA_BYTE(lines, xp)); 00171 * which is faster but gives lousy results! 00172 */ 00173 v00 = (16 - xf) * (16 - yf) * GET_DATA_BYTE(lines, xp); 00174 v10 = xf * (16 - yf) * GET_DATA_BYTE(lines, xp + 1); 00175 v01 = (16 - xf) * yf * GET_DATA_BYTE(lines + wpls, xp); 00176 v11 = xf * yf * GET_DATA_BYTE(lines + wpls, xp + 1); 00177 val = (l_uint8)((v00 + v01 + v10 + v11 + 128) / 256); 00178 SET_DATA_BYTE(lined, j, val); 00179 } 00180 } 00181 00182 return; 00183 } 00184 00185 00186 /*------------------------------------------------------------------* 00187 * 32 bpp grayscale rotation about the UL corner * 00188 *------------------------------------------------------------------*/ 00189 void 00190 rotateAMColorCornerLow(l_uint32 *datad, 00191 l_int32 w, 00192 l_int32 h, 00193 l_int32 wpld, 00194 l_uint32 *datas, 00195 l_int32 wpls, 00196 l_float32 angle, 00197 l_uint32 colorval) 00198 { 00199 l_int32 i, j, wm2, hm2; 00200 l_int32 xpm, ypm, xp, yp, xf, yf; 00201 l_int32 rval, gval, bval; 00202 l_uint32 word00, word01, word10, word11; 00203 l_uint32 *lines, *lined; 00204 l_float32 sina, cosa; 00205 00206 wm2 = w - 2; 00207 hm2 = h - 2; 00208 sina = 16. * sin(angle); 00209 cosa = 16. * cos(angle); 00210 00211 for (i = 0; i < h; i++) { 00212 lined = datad + i * wpld; 00213 for (j = 0; j < w; j++) { 00214 xpm = (l_int32)(j * cosa + i * sina); 00215 ypm = (l_int32)(i * cosa - j * sina); 00216 xp = xpm >> 4; 00217 yp = ypm >> 4; 00218 xf = xpm & 0x0f; 00219 yf = ypm & 0x0f; 00220 00221 /* if off the edge, write input colorval */ 00222 if (xp < 0 || yp < 0 || xp > wm2 || yp > hm2) { 00223 *(lined + j) = colorval; 00224 continue; 00225 } 00226 00227 lines = datas + yp * wpls; 00228 00229 /* do area weighting. Without this, we would 00230 * simply do: 00231 * *(lined + j) = *(lines + xp); 00232 * which is faster but gives lousy results! 00233 */ 00234 word00 = *(lines + xp); 00235 word10 = *(lines + xp + 1); 00236 word01 = *(lines + wpls + xp); 00237 word11 = *(lines + wpls + xp + 1); 00238 rval = ((16 - xf) * (16 - yf) * ((word00 >> L_RED_SHIFT) & 0xff) + 00239 xf * (16 - yf) * ((word10 >> L_RED_SHIFT) & 0xff) + 00240 (16 - xf) * yf * ((word01 >> L_RED_SHIFT) & 0xff) + 00241 xf * yf * ((word11 >> L_RED_SHIFT) & 0xff) + 128) / 256; 00242 gval = ((16 - xf) * (16 - yf) * ((word00 >> L_GREEN_SHIFT) & 0xff) + 00243 xf * (16 - yf) * ((word10 >> L_GREEN_SHIFT) & 0xff) + 00244 (16 - xf) * yf * ((word01 >> L_GREEN_SHIFT) & 0xff) + 00245 xf * yf * ((word11 >> L_GREEN_SHIFT) & 0xff) + 128) / 256; 00246 bval = ((16 - xf) * (16 - yf) * ((word00 >> L_BLUE_SHIFT) & 0xff) + 00247 xf * (16 - yf) * ((word10 >> L_BLUE_SHIFT) & 0xff) + 00248 (16 - xf) * yf * ((word01 >> L_BLUE_SHIFT) & 0xff) + 00249 xf * yf * ((word11 >> L_BLUE_SHIFT) & 0xff) + 128) / 256; 00250 composeRGBPixel(rval, gval, bval, lined + j); 00251 } 00252 } 00253 00254 return; 00255 } 00256 00257 00258 00259 /*------------------------------------------------------------------* 00260 * 8 bpp grayscale rotation about the UL corner * 00261 *------------------------------------------------------------------*/ 00262 void 00263 rotateAMGrayCornerLow(l_uint32 *datad, 00264 l_int32 w, 00265 l_int32 h, 00266 l_int32 wpld, 00267 l_uint32 *datas, 00268 l_int32 wpls, 00269 l_float32 angle, 00270 l_uint8 grayval) 00271 { 00272 l_int32 i, j, wm2, hm2; 00273 l_int32 xpm, ypm, xp, yp, xf, yf; 00274 l_int32 v00, v01, v10, v11; 00275 l_uint8 val; 00276 l_uint32 *lines, *lined; 00277 l_float32 sina, cosa; 00278 00279 wm2 = w - 2; 00280 hm2 = h - 2; 00281 sina = 16. * sin(angle); 00282 cosa = 16. * cos(angle); 00283 00284 for (i = 0; i < h; i++) { 00285 lined = datad + i * wpld; 00286 for (j = 0; j < w; j++) { 00287 xpm = (l_int32)(j * cosa + i * sina); 00288 ypm = (l_int32)(i * cosa - j * sina); 00289 xp = xpm >> 4; 00290 yp = ypm >> 4; 00291 xf = xpm & 0x0f; 00292 yf = ypm & 0x0f; 00293 00294 /* if off the edge, write input grayval */ 00295 if (xp < 0 || yp < 0 || xp > wm2 || yp > hm2) { 00296 SET_DATA_BYTE(lined, j, grayval); 00297 continue; 00298 } 00299 00300 lines = datas + yp * wpls; 00301 00302 /* do area weighting. Without this, we would 00303 * simply do: 00304 * SET_DATA_BYTE(lined, j, GET_DATA_BYTE(lines, xp)); 00305 * which is faster but gives lousy results! 00306 */ 00307 v00 = (16 - xf) * (16 - yf) * GET_DATA_BYTE(lines, xp); 00308 v10 = xf * (16 - yf) * GET_DATA_BYTE(lines, xp + 1); 00309 v01 = (16 - xf) * yf * GET_DATA_BYTE(lines + wpls, xp); 00310 v11 = xf * yf * GET_DATA_BYTE(lines + wpls, xp + 1); 00311 val = (l_uint8)((v00 + v01 + v10 + v11 + 128) / 256); 00312 SET_DATA_BYTE(lined, j, val); 00313 } 00314 } 00315 00316 return; 00317 } 00318 00319 00320 /*------------------------------------------------------------------* 00321 * Fast RGB color rotation about center * 00322 *------------------------------------------------------------------*/ 00323 /*! 00324 * rotateAMColorFastLow() 00325 * 00326 * This is a special simplification of area mapping with division 00327 * of each pixel into 16 sub-pixels. The exact coefficients that 00328 * should be used are the same as for the 4x linear interpolation 00329 * scaling case, and are given there. I tried to approximate these 00330 * as weighted coefficients with a maximum sum of 4, which 00331 * allows us to do the arithmetic in parallel for the R, G and B 00332 * components in a 32 bit pixel. However, there are three reasons 00333 * for not doing that: 00334 * (1) the loss of accuracy in the parallel implementation 00335 * is visually significant 00336 * (2) the parallel implementation (described below) is slower 00337 * (3) the parallel implementation requires allocation of 00338 * a temporary color image 00339 * 00340 * There are 16 cases for the choice of the subpixel, and 00341 * for each, the mapping to the relevant source 00342 * pixels is as follows: 00343 * 00344 * subpixel src pixel weights 00345 * -------- ----------------- 00346 * 0 sp1 00347 * 1 (3 * sp1 + sp2) / 4 00348 * 2 (sp1 + sp2) / 2 00349 * 3 (sp1 + 3 * sp2) / 4 00350 * 4 (3 * sp1 + sp3) / 4 00351 * 5 (9 * sp1 + 3 * sp2 + 3 * sp3 + sp4) / 16 00352 * 6 (3 * sp1 + 3 * sp2 + sp3 + sp4) / 8 00353 * 7 (3 * sp1 + 9 * sp2 + sp3 + 3 * sp4) / 16 00354 * 8 (sp1 + sp3) / 2 00355 * 9 (3 * sp1 + sp2 + 3 * sp3 + sp4) / 8 00356 * 10 (sp1 + sp2 + sp3 + sp4) / 4 00357 * 11 (sp1 + 3 * sp2 + sp3 + 3 * sp4) / 8 00358 * 12 (sp1 + 3 * sp3) / 4 00359 * 13 (3 * sp1 + sp2 + 9 * sp3 + 3 * sp4) / 16 00360 * 14 (sp1 + sp2 + 3 * sp3 + 3 * sp4) / 8 00361 * 15 (sp1 + 3 * sp2 + 3 * sp3 + 9 * sp4) / 16 00362 * 00363 * Another way to visualize this is to consider the area mapping 00364 * (or linear interpolation) coefficients for the pixel sp1. 00365 * Expressed in fourths, they can be written as asymmetric matrix: 00366 * 00367 * 4 3 2 1 00368 * 3 2.25 1.5 0.75 00369 * 2 1.5 1 0.5 00370 * 1 0.75 0.5 0.25 00371 * 00372 * The coefficients for the three neighboring pixels can be 00373 * similarly written. 00374 * 00375 * This is implemented here, where, for each color component, 00376 * we inline its extraction from each participating word, 00377 * construct the linear combination, and combine the results 00378 * into the destination 32 bit RGB pixel, using the appropriate shifts. 00379 * 00380 * It is interesting to note that an alternative method, where 00381 * we do the arithmetic on the 32 bit pixels directly (after 00382 * shifting the components so they won't overflow into each other) 00383 * is significantly inferior. Because we have only 8 bits for 00384 * internal overflows, which can be distributed as 2, 3, 3, it 00385 * is impossible to add these with the correct linear 00386 * interpolation coefficients, which require a sum of up to 16. 00387 * Rounding off to a sum of 4 causes appreciable visual artifacts 00388 * in the rotated image. The code for the inferior method 00389 * can be found in prog/rotatefastalt.c, for reference. 00390 * 00391 * *** Warning: explicit assumption about RGB component ordering *** 00392 */ 00393 void 00394 rotateAMColorFastLow(l_uint32 *datad, 00395 l_int32 w, 00396 l_int32 h, 00397 l_int32 wpld, 00398 l_uint32 *datas, 00399 l_int32 wpls, 00400 l_float32 angle, 00401 l_uint32 colorval) 00402 { 00403 l_int32 i, j, xcen, ycen, wm2, hm2; 00404 l_int32 xdif, ydif, xpm, ypm, xp, yp, xf, yf; 00405 l_uint32 word1, word2, word3, word4, red, blue, green; 00406 l_uint32 *pword, *lines, *lined; 00407 l_float32 sina, cosa; 00408 00409 xcen = w / 2; 00410 wm2 = w - 2; 00411 ycen = h / 2; 00412 hm2 = h - 2; 00413 sina = 4. * sin(angle); 00414 cosa = 4. * cos(angle); 00415 00416 for (i = 0; i < h; i++) { 00417 ydif = ycen - i; 00418 lined = datad + i * wpld; 00419 for (j = 0; j < w; j++) { 00420 xdif = xcen - j; 00421 xpm = (l_int32)(-xdif * cosa - ydif * sina); 00422 ypm = (l_int32)(-ydif * cosa + xdif * sina); 00423 xp = xcen + (xpm >> 2); 00424 yp = ycen + (ypm >> 2); 00425 xf = xpm & 0x03; 00426 yf = ypm & 0x03; 00427 00428 /* if off the edge, write input grayval */ 00429 if (xp < 0 || yp < 0 || xp > wm2 || yp > hm2) { 00430 *(lined + j) = colorval; 00431 continue; 00432 } 00433 00434 lines = datas + yp * wpls; 00435 pword = lines + xp; 00436 00437 switch (xf + 4 * yf) 00438 { 00439 case 0: 00440 *(lined + j) = *pword; 00441 break; 00442 case 1: 00443 word1 = *pword; 00444 word2 = *(pword + 1); 00445 red = 3 * (word1 >> 24) + (word2 >> 24); 00446 green = 3 * ((word1 >> 16) & 0xff) + 00447 ((word2 >> 16) & 0xff); 00448 blue = 3 * ((word1 >> 8) & 0xff) + 00449 ((word2 >> 8) & 0xff); 00450 *(lined + j) = ((red << 22) & 0xff000000) | 00451 ((green << 14) & 0x00ff0000) | 00452 ((blue << 6) & 0x0000ff00); 00453 break; 00454 case 2: 00455 word1 = *pword; 00456 word2 = *(pword + 1); 00457 red = (word1 >> 24) + (word2 >> 24); 00458 green = ((word1 >> 16) & 0xff) + ((word2 >> 16) & 0xff); 00459 blue = ((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff); 00460 *(lined + j) = ((red << 23) & 0xff000000) | 00461 ((green << 15) & 0x00ff0000) | 00462 ((blue << 7) & 0x0000ff00); 00463 break; 00464 case 3: 00465 word1 = *pword; 00466 word2 = *(pword + 1); 00467 red = (word1 >> 24) + 3 * (word2 >> 24); 00468 green = ((word1 >> 16) & 0xff) + 00469 3 * ((word2 >> 16) & 0xff); 00470 blue = ((word1 >> 8) & 0xff) + 00471 3 * ((word2 >> 8) & 0xff); 00472 *(lined + j) = ((red << 22) & 0xff000000) | 00473 ((green << 14) & 0x00ff0000) | 00474 ((blue << 6) & 0x0000ff00); 00475 break; 00476 case 4: 00477 word1 = *pword; 00478 word3 = *(pword + wpls); 00479 red = 3 * (word1 >> 24) + (word3 >> 24); 00480 green = 3 * ((word1 >> 16) & 0xff) + 00481 ((word3 >> 16) & 0xff); 00482 blue = 3 * ((word1 >> 8) & 0xff) + 00483 ((word3 >> 8) & 0xff); 00484 *(lined + j) = ((red << 22) & 0xff000000) | 00485 ((green << 14) & 0x00ff0000) | 00486 ((blue << 6) & 0x0000ff00); 00487 break; 00488 case 5: 00489 word1 = *pword; 00490 word2 = *(pword + 1); 00491 word3 = *(pword + wpls); 00492 word4 = *(pword + wpls + 1); 00493 red = 9 * (word1 >> 24) + 3 * (word2 >> 24) + 00494 3 * (word3 >> 24) + (word4 >> 24); 00495 green = 9 * ((word1 >> 16) & 0xff) + 00496 3 * ((word2 >> 16) & 0xff) + 00497 3 * ((word3 >> 16) & 0xff) + 00498 ((word4 >> 16) & 0xff); 00499 blue = 9 * ((word1 >> 8) & 0xff) + 00500 3 * ((word2 >> 8) & 0xff) + 00501 3 * ((word3 >> 8) & 0xff) + 00502 ((word4 >> 8) & 0xff); 00503 *(lined + j) = ((red << 20) & 0xff000000) | 00504 ((green << 12) & 0x00ff0000) | 00505 ((blue << 4) & 0x0000ff00); 00506 break; 00507 case 6: 00508 word1 = *pword; 00509 word2 = *(pword + 1); 00510 word3 = *(pword + wpls); 00511 word4 = *(pword + wpls + 1); 00512 red = 3 * (word1 >> 24) + 3 * (word2 >> 24) + 00513 (word3 >> 24) + (word4 >> 24); 00514 green = 3 * ((word1 >> 16) & 0xff) + 00515 3 * ((word2 >> 16) & 0xff) + 00516 ((word3 >> 16) & 0xff) + 00517 ((word4 >> 16) & 0xff); 00518 blue = 3 * ((word1 >> 8) & 0xff) + 00519 3 * ((word2 >> 8) & 0xff) + 00520 ((word3 >> 8) & 0xff) + 00521 ((word4 >> 8) & 0xff); 00522 *(lined + j) = ((red << 21) & 0xff000000) | 00523 ((green << 13) & 0x00ff0000) | 00524 ((blue << 5) & 0x0000ff00); 00525 break; 00526 case 7: 00527 word1 = *pword; 00528 word2 = *(pword + 1); 00529 word3 = *(pword + wpls); 00530 word4 = *(pword + wpls + 1); 00531 red = 3 * (word1 >> 24) + 9 * (word2 >> 24) + 00532 (word3 >> 24) + 3 * (word4 >> 24); 00533 green = 3 * ((word1 >> 16) & 0xff) + 00534 9 * ((word2 >> 16) & 0xff) + 00535 ((word3 >> 16) & 0xff) + 00536 3 * ((word4 >> 16) & 0xff); 00537 blue = 3 * ((word1 >> 8) & 0xff) + 00538 9 * ((word2 >> 8) & 0xff) + 00539 ((word3 >> 8) & 0xff) + 00540 3 * ((word4 >> 8) & 0xff); 00541 *(lined + j) = ((red << 20) & 0xff000000) | 00542 ((green << 12) & 0x00ff0000) | 00543 ((blue << 4) & 0x0000ff00); 00544 break; 00545 case 8: 00546 word1 = *pword; 00547 word3 = *(pword + wpls); 00548 red = (word1 >> 24) + (word3 >> 24); 00549 green = ((word1 >> 16) & 0xff) + ((word3 >> 16) & 0xff); 00550 blue = ((word1 >> 8) & 0xff) + ((word3 >> 8) & 0xff); 00551 *(lined + j) = ((red << 23) & 0xff000000) | 00552 ((green << 15) & 0x00ff0000) | 00553 ((blue << 7) & 0x0000ff00); 00554 break; 00555 case 9: 00556 word1 = *pword; 00557 word2 = *(pword + 1); 00558 word3 = *(pword + wpls); 00559 word4 = *(pword + wpls + 1); 00560 red = 3 * (word1 >> 24) + (word2 >> 24) + 00561 3 * (word3 >> 24) + (word4 >> 24); 00562 green = 3 * ((word1 >> 16) & 0xff) + ((word2 >> 16) & 0xff) + 00563 3 * ((word3 >> 16) & 0xff) + ((word4 >> 16) & 0xff); 00564 blue = 3 * ((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff) + 00565 3 * ((word3 >> 8) & 0xff) + ((word4 >> 8) & 0xff); 00566 *(lined + j) = ((red << 21) & 0xff000000) | 00567 ((green << 13) & 0x00ff0000) | 00568 ((blue << 5) & 0x0000ff00); 00569 break; 00570 case 10: 00571 word1 = *pword; 00572 word2 = *(pword + 1); 00573 word3 = *(pword + wpls); 00574 word4 = *(pword + wpls + 1); 00575 red = (word1 >> 24) + (word2 >> 24) + 00576 (word3 >> 24) + (word4 >> 24); 00577 green = ((word1 >> 16) & 0xff) + ((word2 >> 16) & 0xff) + 00578 ((word3 >> 16) & 0xff) + ((word4 >> 16) & 0xff); 00579 blue = ((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff) + 00580 ((word3 >> 8) & 0xff) + ((word4 >> 8) & 0xff); 00581 *(lined + j) = ((red << 22) & 0xff000000) | 00582 ((green << 14) & 0x00ff0000) | 00583 ((blue << 6) & 0x0000ff00); 00584 break; 00585 case 11: 00586 word1 = *pword; 00587 word2 = *(pword + 1); 00588 word3 = *(pword + wpls); 00589 word4 = *(pword + wpls + 1); 00590 red = (word1 >> 24) + 3 * (word2 >> 24) + 00591 (word3 >> 24) + 3 * (word4 >> 24); 00592 green = ((word1 >> 16) & 0xff) + 3 * ((word2 >> 16) & 0xff) + 00593 ((word3 >> 16) & 0xff) + 3 * ((word4 >> 16) & 0xff); 00594 blue = ((word1 >> 8) & 0xff) + 3 * ((word2 >> 8) & 0xff) + 00595 ((word3 >> 8) & 0xff) + 3 * ((word4 >> 8) & 0xff); 00596 *(lined + j) = ((red << 21) & 0xff000000) | 00597 ((green << 13) & 0x00ff0000) | 00598 ((blue << 5) & 0x0000ff00); 00599 break; 00600 case 12: 00601 word1 = *pword; 00602 word3 = *(pword + wpls); 00603 red = (word1 >> 24) + 3 * (word3 >> 24); 00604 green = ((word1 >> 16) & 0xff) + 00605 3 * ((word3 >> 16) & 0xff); 00606 blue = ((word1 >> 8) & 0xff) + 00607 3 * ((word3 >> 8) & 0xff); 00608 *(lined + j) = ((red << 22) & 0xff000000) | 00609 ((green << 14) & 0x00ff0000) | 00610 ((blue << 6) & 0x0000ff00); 00611 break; 00612 case 13: 00613 word1 = *pword; 00614 word2 = *(pword + 1); 00615 word3 = *(pword + wpls); 00616 word4 = *(pword + wpls + 1); 00617 red = 3 * (word1 >> 24) + (word2 >> 24) + 00618 9 * (word3 >> 24) + 3 * (word4 >> 24); 00619 green = 3 * ((word1 >> 16) & 0xff) + ((word2 >> 16) & 0xff) + 00620 9 * ((word3 >> 16) & 0xff) + 3 * ((word4 >> 16) & 0xff); 00621 blue = 3 *((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff) + 00622 9 * ((word3 >> 8) & 0xff) + 3 * ((word4 >> 8) & 0xff); 00623 *(lined + j) = ((red << 20) & 0xff000000) | 00624 ((green << 12) & 0x00ff0000) | 00625 ((blue << 4) & 0x0000ff00); 00626 break; 00627 case 14: 00628 word1 = *pword; 00629 word2 = *(pword + 1); 00630 word3 = *(pword + wpls); 00631 word4 = *(pword + wpls + 1); 00632 red = (word1 >> 24) + (word2 >> 24) + 00633 3 * (word3 >> 24) + 3 * (word4 >> 24); 00634 green = ((word1 >> 16) & 0xff) +((word2 >> 16) & 0xff) + 00635 3 * ((word3 >> 16) & 0xff) + 3 * ((word4 >> 16) & 0xff); 00636 blue = ((word1 >> 8) & 0xff) + ((word2 >> 8) & 0xff) + 00637 3 * ((word3 >> 8) & 0xff) + 3 * ((word4 >> 8) & 0xff); 00638 *(lined + j) = ((red << 21) & 0xff000000) | 00639 ((green << 13) & 0x00ff0000) | 00640 ((blue << 5) & 0x0000ff00); 00641 break; 00642 case 15: 00643 word1 = *pword; 00644 word2 = *(pword + 1); 00645 word3 = *(pword + wpls); 00646 word4 = *(pword + wpls + 1); 00647 red = (word1 >> 24) + 3 * (word2 >> 24) + 00648 3 * (word3 >> 24) + 9 * (word4 >> 24); 00649 green = ((word1 >> 16) & 0xff) + 3 * ((word2 >> 16) & 0xff) + 00650 3 * ((word3 >> 16) & 0xff) + 9 * ((word4 >> 16) & 0xff); 00651 blue = ((word1 >> 8) & 0xff) + 3 * ((word2 >> 8) & 0xff) + 00652 3 * ((word3 >> 8) & 0xff) + 9 * ((word4 >> 8) & 0xff); 00653 *(lined + j) = ((red << 20) & 0xff000000) | 00654 ((green << 12) & 0x00ff0000) | 00655 ((blue << 4) & 0x0000ff00); 00656 break; 00657 default: 00658 fprintf(stderr, "shouldn't get here\n"); 00659 break; 00660 } 00661 } 00662 } 00663 00664 return; 00665 } 00666 00667