Back to index

lightning-sunbird  0.9+nobinonly
imgScaler.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Tomas Mšller.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Tomas Mšller
00023  *   Tim Rowley <tor@cs.brown.edu>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include "imgScaler.h"
00042 
00043 // Scaling code from Graphics Gems book III                     
00044 // http://www.acm.org/pubs/tog/GraphicsGems/gemsiii/fastBitmap.c
00045 //
00046 // License states - "All code here can be used without restrictions."
00047 // http://www.acm.org/pubs/tog/GraphicsGems/
00048 
00049 /*
00050 Fast Bitmap Stretching
00051 Tomas Mšller
00052 */
00053 
00054 static void
00055 Stretch32(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00056          unsigned yr, unsigned yw,
00057          unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
00058          unsigned char *aSrcImage, unsigned aSrcStride,
00059          unsigned char *aDstImage, unsigned aDstStride);
00060 
00061 static void
00062 Stretch24(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00063          unsigned yr, unsigned yw,
00064          unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
00065          unsigned char *aSrcImage, unsigned aSrcStride,
00066          unsigned char *aDstImage, unsigned aDstStride);
00067 
00068 static void
00069 Stretch8(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00070         unsigned yr, unsigned yw,
00071         unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
00072         unsigned char *aSrcImage, unsigned aSrcStride,
00073         unsigned char *aDstImage, unsigned aDstStride);
00074 
00075 static void
00076 Stretch1(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00077         unsigned yr, unsigned yw,
00078         unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
00079         unsigned char *aSrcImage, unsigned aSrcStride,
00080         unsigned char *aDstImage, unsigned aDstStride);
00081 
00082 /**********************************************************
00083  RectStretch enlarges or diminishes a source rectangle of a bitmap to
00084  a destination rectangle. The source rectangle is selected by the two
00085  points (xs1,ys1) and (xs2,ys2), and the destination rectangle by
00086  (xd1,yd1) and (xd2,yd2). Since readability of source-code is wanted,
00087  some optimizations have been left out for the reader: It's possible
00088  to read one line at a time, by first stretching in x-direction and
00089  then stretching that bitmap in y-direction.
00090 
00091  Entry:
00092     aSrcWidth, aSrcHeight - size of entire original image
00093     aDstWidth, aDstHeight - size of entire scaled image
00094 
00095     aStartColumn, aStartRow - upper corner of desired area (inclusive)
00096     aEndColumn, aEndRow - bottom corner of desired area (inclusive)
00097     
00098     unsigned char *aSrcImage, aSrcStride - start of original image data
00099     unsigned char *aDstStride, aDstStride - start of desired area image data
00100 
00101     unsigned aDepth - bit depth of image (24, 8, or 1)
00102 
00103 **********************************************************/
00104 NS_GFX_(void)
00105 RectStretch(unsigned aSrcWidth, unsigned aSrcHeight,
00106            unsigned aDstWidth, unsigned aDstHeight,
00107            unsigned aStartColumn, unsigned aStartRow,
00108            unsigned aEndColumn, unsigned aEndRow,
00109            unsigned char *aSrcImage, unsigned aSrcStride,
00110            unsigned char *aDstImage, unsigned aDstStride,
00111            unsigned aDepth)
00112 {
00113     int e;
00114     unsigned dx, dy;
00115     void (*Stretch)(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00116                   unsigned yr, unsigned yw,
00117                   unsigned aStartRow, unsigned aStartColumn,
00118                   unsigned aEndColumn,
00119                   unsigned char *aSrcImage, unsigned aSrcStride,
00120                   unsigned char *aDstImage, unsigned aDstStride);
00121 
00122     unsigned xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2;
00123 
00124     xs1 = ys1 = xd1 = yd1 = 0;
00125     xs2 = aSrcWidth  - 1;
00126     ys2 = aSrcHeight - 1;
00127     xd2 = aDstWidth  - 1;
00128     yd2 = aDstHeight - 1;
00129 
00130 //    fprintf(stderr, "RS (%d %d)-(%d %d) (%d %d)-(%d %d) %d %d %d\n",
00131 //         xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2,
00132 //         aSrcStride, aDstStride, aDepth);
00133 
00134     switch (aDepth) {
00135     case 32:
00136        Stretch = Stretch32;
00137        break;
00138     case 24:
00139        Stretch = Stretch24;
00140        break;
00141     case 8:
00142        Stretch = Stretch8;
00143        break;
00144     case 1:
00145        Stretch = Stretch1;
00146        break;
00147     default:
00148        return;
00149     }
00150     dx = yd2 - yd1;
00151     dy = ys2 - ys1;
00152     e = dy - dx;
00153     dy += 1;
00154     if (!dx)
00155        dx = 1;
00156     for (yd1 = 0; yd1 <= aEndRow; yd1++) {
00157        if (yd1 >= aStartRow)
00158            Stretch(xd1, xd2, xs1, xs2, ys1, yd1,
00159                   aStartRow, aStartColumn, aEndColumn,
00160                   aSrcImage, aSrcStride, aDstImage, aDstStride);
00161        while (e >= 0) {
00162            ys1++;
00163            e -= dx;
00164        }
00165        e += dy;
00166     }
00167 }
00168 
00169 /**********************************************************
00170  Stretches a horizontal source line onto a horizontal destination
00171  line. Used by RectStretch.
00172 
00173  Entry:
00174        x1,x2 - x-coordinates of the destination line
00175        y1,y2 - x-coordinates of the source line
00176        yr    - y-coordinate of source line
00177        yw    - y-coordinate of destination line
00178 **********************************************************/
00179 
00180 static void
00181 Stretch32(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00182          unsigned yr, unsigned yw,
00183          unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
00184          unsigned char *aSrcImage, unsigned aSrcStride,
00185          unsigned char *aDstImage, unsigned aDstStride)
00186 {
00187     int e;
00188     unsigned dx, dy, d;
00189     unsigned char *src, *dst;
00190 
00191     dx = x2 - x1;
00192     dy = y2 - y1;
00193     e = dy - dx;
00194     dy += 1;
00195     src = aSrcImage + yr * aSrcStride + 4 * y1;
00196     dst = aDstImage + (yw - aStartRow) * aDstStride;
00197     if (!dx)
00198        dx = 1;
00199     for (d = 0; d <= aEndColumn; d++) {
00200        if (d >= aStartColumn) {
00201            *dst++ = src[0];
00202            *dst++ = src[1];
00203            *dst++ = src[2];
00204            *dst++ = src[3];
00205        }
00206        while (e >= 0) {
00207            src += 4;
00208            e -= dx;
00209        }
00210        e += dy;
00211     }
00212 }
00213 
00214 static void
00215 Stretch24(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00216          unsigned yr, unsigned yw,
00217          unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
00218          unsigned char *aSrcImage, unsigned aSrcStride,
00219          unsigned char *aDstImage, unsigned aDstStride)
00220 {
00221     int e;
00222     unsigned dx, dy, d;
00223     unsigned char *src, *dst;
00224 
00225     dx = x2 - x1;
00226     dy = y2 - y1;
00227     e = dy - dx;
00228     dy += 1;
00229     src = aSrcImage + yr * aSrcStride + 3 * y1;
00230     dst = aDstImage + (yw - aStartRow) * aDstStride;
00231     if (!dx)
00232        dx = 1;
00233     for (d = 0; d <= aEndColumn; d++) {
00234        if (d >= aStartColumn) {
00235            *dst++ = src[0];
00236            *dst++ = src[1];
00237            *dst++ = src[2];
00238        }
00239        while (e >= 0) {
00240            src += 3;
00241            e -= dx;
00242        }
00243        e += dy;
00244     }
00245 }
00246 
00247 static void
00248 Stretch8(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00249         unsigned yr, unsigned yw,
00250         unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
00251         unsigned char *aSrcImage, unsigned aSrcStride,
00252         unsigned char *aDstImage, unsigned aDstStride)
00253 {
00254     int e;
00255     unsigned dx, dy, d;
00256     unsigned char *src, *dst;
00257 
00258     dx = x2 - x1;
00259     dy = y2 - y1;
00260     e = dy - dx;
00261     dy += 1;
00262     src = aSrcImage + yr * aSrcStride + y1;
00263     dst = aDstImage + (yw - aStartRow) * aDstStride;
00264     if (!dx)
00265        dx = 1;
00266     for (d = 0; d <= aEndColumn; d++) {
00267        if (d >= aStartColumn) {
00268            *dst = *src;
00269            dst++;
00270        }
00271        while (e >= 0) {
00272            src++;
00273            e -= dx;
00274        }
00275        e += dy;
00276     }
00277 }
00278 
00279 static void
00280 Stretch1(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
00281         unsigned yr, unsigned yw,
00282         unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
00283         unsigned char *aSrcImage, unsigned aSrcStride,
00284         unsigned char *aDstImage, unsigned aDstStride)
00285 {
00286     int e;
00287     unsigned dx, dy, d;
00288 
00289     dx = x2 - x1;
00290     dy = y2 - y1;
00291     e = dy - dx;
00292     dy += 1;
00293     if (!dx)
00294        dx = 1;
00295     for (d = 0; d <= aEndColumn; d++) {
00296        if ((d >= aStartColumn) &&
00297            (*(aSrcImage + yr * aSrcStride + (y1 >> 3)) & 1 << (7 - y1 & 0x7)))
00298            *(aDstImage +
00299              (yw - aStartRow) * aDstStride +
00300              ((x1 - aStartColumn) >> 3)) 
00301               |= 1 << (7 - x1 & 0x7);
00302        while (e >= 0) {
00303            y1++;
00304            e -= dx;
00305        }
00306        x1++;
00307        e += dy;
00308     }
00309 }