Leptonica 1.68
C Image Processing Library

rotateamlow.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  *  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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines