Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

bitmap.cpp

Go to the documentation of this file.
00001 /*  Bitmap functions
00002 
00003     27.06.2001: tk, initial implementation.
00004 
00005     Copyright (c)2000 by Thomas Kindler, thomas.kindler@gmx.de
00006 
00007     This program is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU General Public License as
00009     published by the Free Software Foundation; either version 2 of
00010     the License, or (at your option) any later version. Read the
00011     full License at http://www.gnu.org/copyleft for more details.
00012 */
00013 
00014 // include files -----
00015 //
00016 #include "bitmap.h"
00017 #include <assert.h>
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <mem.h>
00021 
00022 
00026 static BM_BlitFunc *blitFuncs[] = {
00027   NULL,           BM_Blit_Nor,   BM_Blit_NotAnd,  BM_Blit_NotCopy,
00028   BM_Blit_AndNot, NULL,          BM_Blit_Xor,     BM_Blit_Nand,
00029   BM_Blit_And,    BM_Blit_Nexor, NULL,            BM_Blit_NotOr,
00030   BM_Blit_Copy,   BM_Blit_OrNot, BM_Blit_Or,      NULL
00031 };
00032 
00033 
00044 Bitmap *BM_Alloc(int w, int h)
00045 {
00046   unsigned size = w*((h+7)>>3);
00047   size += size & 1;   // make size a multiple of two.
00048 
00049   Bitmap *bm = (Bitmap*)malloc(sizeof(Bitmap)+size);
00050   if (!bm)
00051     return NULL;
00052 
00053   bm->width  = w;
00054   bm->height = h;
00055   bm->bmBitsSize = size;
00056   return bm;
00057 }
00058 
00059 
00066 Bitmap *BM_Copy(Bitmap *bm)
00067 {
00068   Bitmap *copy = BM_Alloc(bm->width, bm->height);
00069   if (!copy)
00070     return NULL;
00071 
00072   memcpy(copy->bmBits, bm->bmBits, copy->bmBitsSize);
00073   return copy;
00074 }
00075 
00076 
00077 
00087 void BM_Free(Bitmap *bm)
00088 {
00089   if (bm) {
00090     bm->width  = 0;
00091     bm->height = 0;
00092     bm->bmBitsSize = 0;
00093     free(bm);
00094   }
00095 }
00096 
00097 
00104 void BM_Clear(Bitmap *bm, char pattern)
00105 {
00106   memset(bm->bmBits, pattern, bm->bmBitsSize);
00107 }
00108 
00109 
00115 void BM_Invert(Bitmap *bm)
00116 {
00117   char     *bits = bm->bmBits;
00118   unsigned  size = bm->bmBitsSize;
00119 
00120   asm {
00121     pushf
00122     push  ax
00123     push  cx
00124     push  si 
00125     push  di
00126     push  ds
00127     push  es
00128     cld
00129 
00130     lds   si, bits
00131     les   di, bits
00132 
00133     mov   cx, size
00134     shr   cx, 1
00135 l1: lodsw
00136     not   ax
00137     stosw
00138     loop  l1
00139 
00140     pop   es
00141     pop   ds
00142     pop   di
00143     pop   si
00144     pop   cx
00145     pop   ax
00146     popf
00147   }
00148 }
00149 
00150 
00161 void BM_Scroll(Bitmap *bm, int dx, int dy)
00162 {
00163   Bitmap *tmp = BM_Copy(bm);
00164   assert(tmp != NULL);
00165 
00166   BM_Clear(bm);
00167   BM_Blit(bm, -dx, -dy, tmp);
00168   BM_Free(tmp);
00169 }
00170 
00171 
00183 Bitmap *BM_Load(char *fn)
00184 {
00185   printf("loading \"%s\".. ", fn);
00186 
00187   FILE *f = fopen( fn, "rb" );
00188   if (!f) {
00189     perror("");
00190     return NULL;
00191   }
00192 
00193   BitmapFileHeader  bmfh = {0};
00194   fread(&bmfh, 1, sizeof(bmfh), f);
00195 
00196   if (bmfh.bfType        != 0x4D42 ||
00197       bmfh.biPlanes      != 1      ||
00198       bmfh.biBitCount    != 1      ||
00199       bmfh.biCompression != 0       )
00200   {
00201     printf( "invalid format.\n" );
00202     fclose(f);
00203     return NULL;
00204   }
00205 
00206   fseek(f, bmfh.bfOffBits, SEEK_SET);
00207 
00208   Bitmap *bm = BM_Alloc(bmfh.biWidth, abs(bmfh.biHeight));
00209   if (!bm) {
00210     printf("can't alloc bitmap.\n");
00211     fclose(f);
00212     return NULL;
00213   }
00214   BM_Clear(bm);
00215 
00216   char pad[4];
00217   int  padBytes = (4-(bmfh.biWidth+7)>>3) & 3;
00218 
00219   for (int y=abs(bmfh.biHeight)-1; y>=0; y--) {
00220     unsigned char  *dst = bm->bmBits + (y>>3)*bm->width;
00221     unsigned char ymask = 1<<(y&7), xmask = 0, src;
00222 
00223     for (int x=0; x<bm->width; x++) {
00224       if (!xmask) {
00225         src   = ~fgetc(f);
00226         xmask = 0x80;
00227       }
00228       if (src & xmask)
00229         *dst |= ymask;
00230       xmask >>= 1;
00231       dst++;
00232     }
00233     fread(pad, 1, padBytes, f);
00234   }
00235 
00236   fclose(f);
00237   printf( "%dx%d (%u bytes).\n", bm->width,
00238           bm->height, bm->bmBitsSize);
00239   return bm;
00240 }
00241 
00242 
00252 void  BM_Save(Bitmap *bm, char *fn)
00253 {
00254   BitmapFileHeader  bmfh;
00255 
00256   int imagesize = (((bm->width+31)>>5)<<2) * bm->height;
00257 
00258   bmfh.bfType = 0x4D42;
00259   bmfh.bfSize = sizeof(bmfh) + imagesize;
00260   bmfh.bfReserved1 = 0;
00261   bmfh.bfReserved2 = 0;
00262   bmfh.bfOffBits = sizeof(bmfh);
00263 
00264   bmfh.biSize = 40;
00265   bmfh.biWidth = bm->width;
00266   bmfh.biHeight = bm->height;
00267   bmfh.biPlanes = 1;
00268   bmfh.biBitCount = 1;
00269   bmfh.biCompression = 0;
00270   bmfh.biSizeImage = imagesize;
00271 
00272   bmfh.biXPelsPerMeter = DPI2PPM(72);
00273   bmfh.biYPelsPerMeter = DPI2PPM(72);
00274   bmfh.biClrUsed = 2;
00275   bmfh.biClrImportant = 2;
00276 
00277   bmfh.color0 = BMP_BGCOLOR;
00278   bmfh.color1 = BMP_FGCOLOR;
00279 
00280   printf("saving \"%s\".. ", fn);
00281   FILE *f = fopen(fn, "wb");
00282   if (!f) {
00283     perror("");
00284     return;
00285   }
00286 
00287   fwrite(&bmfh, sizeof(bmfh), 1, f);
00288 
00289   char pad[4] = {0};
00290   int  padlen = (4-(bm->width+7)>>3) & 3;
00291 
00292   for (int y=bm->height-1; y>=0; y--) {
00293     unsigned char *src   = &bm->bmBits[(y>>3)*bm->width];
00294     unsigned char  ymask = 1<<(y&7), xmask = 0x80, c=0;
00295 
00296     for (int x=0; x<bm->width; x++) {
00297       if (*src++ & ymask)
00298         c |= xmask;
00299       xmask >>= 1;
00300       if (!xmask) {
00301         fputc(c, f);
00302         c = 0;
00303         xmask = 0x80;
00304       }
00305     }
00306     if (xmask != 0x80)
00307       fputc(c, f);
00308 
00309     fwrite(pad, padlen, 1, f);
00310   }
00311 
00312   fclose(f);
00313   printf("ok.\n");
00314 }
00315 
00316 
00335 void BM_Blit( Bitmap *dst, int x, int y, Bitmap *src, int u, int v,
00336               int w, int h, int mode )
00337 {
00338   if (w==-1)  w = src->width;
00339   if (h==-1)  h = src->height;
00340 
00341   // clip x/u coordinates
00342   //
00343   if (x<0) {
00344     u += -x;
00345     w -= -x;
00346     x  =  0;
00347   }
00348   if (x+w >= dst->width)
00349     w -= (x+w)-dst->width;
00350 
00351   if (u<0) {
00352     x += -u;
00353     w -= -u;
00354     u  =  0;
00355   }
00356   if (u+w >= src->width)
00357     w -= (u+w)-src->width;
00358 
00359   if (w<=0)
00360     return;
00361 
00362   // clip y/v coordinates
00363   //
00364   if (y<0)
00365     v += -y,  h -= -y,  y = 0;
00366   if (y+h >= dst->height)
00367     h -= (y+h)-dst->height;
00368 
00369   if (v<0)
00370     y += -v,  h -= -v,  v = 0;
00371   if (v+h >= src->height)
00372     h -= (v+h) - src->height;
00373 
00374   if (h<=0)
00375     return;
00376 
00377   BM_FastBlit(dst, x, y, src, u, v, w, h, mode);
00378 }
00379 
00380 
00398 void BM_FastBlit(Bitmap *dst, int x, int y, Bitmap *src, int u, int v,
00399                  int w, int h, int mode)
00400 {
00401   if (w==-1)  w = src->width;
00402   if (h==-1)  h = src->height;
00403 
00404   // calculate destination masks
00405   //
00406   unsigned char fbm, lbm;
00407   fbm = 0xff << (   y & 7);
00408   lbm = 0xff >> (-y-h & 7);
00409 
00410   // calculate number of pages
00411   //
00412   int pages = ((y+h+7)>>3) - (y>>3);
00413   if (pages == 1)
00414     fbm &= lbm;
00415 
00416   // calculate pixel shift
00417   //
00418   int shift = (v&7)-(y&7);
00419   if (shift < 0) {
00420     v     -= 8;
00421     shift &= 7;
00422   }
00423 
00424 /*
00425   printf("dst: "); BM_Info(dst);
00426   printf("src: "); BM_Info(src);
00427   printf(
00428     "  %p, x=%d, y=%d, %p, u=%d, v=%d,\n"
00429     "  w=%d, pages=%d, shift=%d, fbm=%02x, lbm=%02x, mode=%d\n",
00430     dst, x, y, src, u, v, w, pages, shift, fbm, lbm, mode
00431   );
00432 */
00433   BM_BlitFunc *blitter = blitFuncs[mode & 15];
00434   if (blitter)
00435     blitter( &dst->bmBits[x+(y>>3)*dst->width], dst->width,
00436              &src->bmBits[u+(v>>3)*src->width], src->width,
00437              w, pages, shift, fbm, lbm );
00438 }

Generated on Sun Aug 4 21:47:26 2002 for k/os mp3v2 by doxygen1.2.16