src/bitmap.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. VF_MakeScaledBitmap
  2. VF_RotatedBitmap
  3. VF_ReflectedBitmap
  4. VF_CopyBitmap
  5. VF_FillBitmap
  6. VF_ClearBitmap
  7. VF_MinimizeBitmap
  8. vf_alloc_bitmap
  9. vf_alloc_bitmap_with_metric1
  10. vf_alloc_bitmap_with_metric2
  11. VF_FreeBitmap
  12. vf_free_bitmap
  13. VF_DumpBitmap
  14. vf_dump_bitmap

   1 /*
   2  * bitmap.c - a module for bitmap related procedures
   3  * by Hirotsugu Kakugawa
   4  *
   5  */
   6 /*
   7  * Copyright (C) 1996-1999  Hirotsugu Kakugawa. 
   8  * All rights reserved.
   9  *
  10  * This file is part of the VFlib Library.  This library is free
  11  * software; you can redistribute it and/or modify it under the terms of
  12  * the GNU Library General Public License as published by the Free
  13  * Software Foundation; either version 2 of the License, or (at your
  14  * option) any later version.  This library is distributed in the hope
  15  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  16  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  17  * PURPOSE.  See the GNU Library General Public License for more details.
  18  * You should have received a copy of the GNU Library General Public
  19  * License along with this library; if not, write to the Free Software
  20  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21  */
  22 #include <stdio.h>
  23 #include <stdlib.h>
  24 #ifdef HAVE_UNISTD_H
  25 #  include <unistd.h>
  26 #endif
  27 #include <math.h>
  28 #include "config.h"
  29 #include "VFlib-3_6.h"
  30 #include "VFsys.h"
  31 #include "bitmap.h"
  32 #include "consts.h"
  33 
  34 
  35 
  36 /**
  37  ** VF_MakeScaledBitmap
  38  **/
  39 Public VF_BITMAP
  40 VF_MakeScaledBitmap(VF_BITMAP src_bm, double mag_x, double mag_y)
     /* [<][>][^][v][top][bottom][index][help] */
  41 { /* NOTE: CALLER MUST FREE THE BITMAP RETURNED BY THIS ROUTINE. */
  42   int            new_width, new_height;
  43   VF_BITMAP      new_bm;
  44   int            x0, y0, x1, y1, x2, xb, bw;
  45   double         o_mag_x, o_mag_y;
  46   unsigned char  *p0, *p1, *p1u, *p1l, d, d1, d2;
  47   static unsigned char  scale_bit_table[] = {
  48     0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
  49   };
  50 
  51   vf_error = 0;
  52   if (src_bm == NULL)
  53     return NULL;
  54 
  55   o_mag_x = mag_x; 
  56   o_mag_y = mag_y; 
  57 
  58   if (mag_x < 0)
  59     mag_x = 0 - mag_x;
  60   if (mag_y < 0)
  61     mag_y = 0 - mag_y;
  62 
  63   new_width  = (int)ceil(mag_x * src_bm->bbx_width);
  64   new_height = (int)ceil(mag_y * src_bm->bbx_height);
  65   if (   (src_bm->bbx_width  == new_width)
  66       && (src_bm->bbx_height == new_height))
  67     return VF_CopyBitmap(src_bm);
  68   
  69   if ((new_bm = vf_alloc_bitmap(new_width, new_height)) == NULL){
  70     vf_error = VF_ERR_NO_MEMORY;
  71     return NULL;
  72   }
  73 
  74   new_bm->off_x = toint(mag_x * src_bm->off_x);
  75   new_bm->off_y = toint(mag_y * src_bm->off_y);
  76   new_bm->mv_x  = toint(mag_x * src_bm->mv_x);
  77   new_bm->mv_y  = toint(mag_y * src_bm->mv_y);
  78 
  79   if ((new_width < 2) || (new_height < 2))
  80     return new_bm;
  81 
  82   if ((mag_x <= 1.0) && (mag_y <= 1.0)){
  83     p0 = src_bm->bitmap;
  84     for (y0 = 0; y0 < src_bm->bbx_height; y0++){
  85       y1 = mag_y * y0;
  86       for (x0 = 0; x0 < src_bm->bbx_width; x0++){
  87         x1 = mag_x * x0;
  88         if ((p0[x0/8] & scale_bit_table[x0%8]) != 0){
  89           new_bm->bitmap[y1 * new_bm->raster + x1/8]
  90             |= scale_bit_table[x1%8];
  91         }
  92       }
  93       p0 = &p0[src_bm->raster];
  94     }
  95 
  96   } else if ((mag_x > 1.0) && (mag_y > 1.0)){
  97     p1 = new_bm->bitmap;
  98     for (y1 = 0; y1 < new_bm->bbx_height; y1++){
  99       y0 = y1 / mag_y;
 100       for (x1 = 0; x1 < new_bm->bbx_width; x1++){
 101         x0 = x1 / mag_x;
 102         if ((src_bm->bitmap[y0 * src_bm->raster + x0/8] 
 103              & scale_bit_table[x0%8]) != 0){
 104           p1[x1/8] |= scale_bit_table[x1%8];
 105         }
 106       }
 107       p1 = &p1[new_bm->raster];
 108     }
 109 
 110   } else if ((mag_x > 1.0) && (mag_y <= 1.0)){
 111     p0 = src_bm->bitmap;
 112     for (y0 = 0; y0 < src_bm->bbx_height; y0++){
 113       y1 = y0 * mag_y;
 114       for (x1 = 0; x1 < new_bm->bbx_width; x1++){
 115         x0 = x1 / mag_x;
 116         if ((p0[x0/8] & scale_bit_table[x0%8]) != 0){
 117           new_bm->bitmap[y1 * new_bm->raster + (x1/8)] 
 118             |= scale_bit_table[x1%8];
 119         }
 120       }
 121       p0 = &p0[src_bm->raster];
 122     }
 123 
 124   } else {/*((mag_x <= 1.0) && (mag_y > 1.0))*/
 125     p1 = new_bm->bitmap;
 126     for (y1 = 0; y1 < new_bm->bbx_height; y1++){
 127       y0 = y1 / mag_y;
 128       for (x0 = 0; x0 < src_bm->bbx_width; x0++){
 129         x1 = x0 * mag_x;
 130         if ((src_bm->bitmap[y0 * src_bm->raster + x0/8] 
 131              & scale_bit_table[x0%8]) != 0){
 132           p1[x1/8] |= scale_bit_table[x1%8];
 133         }
 134       }
 135       p1 = &p1[new_bm->raster];
 136     }
 137   }
 138 
 139 
 140   if (o_mag_y < 0){
 141     bw = (new_bm->bbx_width + 7) / 8;
 142     for (y1 = 0; y1 < new_bm->bbx_height/2; y1++){
 143       p1u = &new_bm->bitmap[new_bm->raster * y1];
 144       p1l = &new_bm->bitmap[new_bm->raster * (new_bm->bbx_height - y1 - 1)];
 145       for (xb = 0; xb < bw; xb++){
 146         d = *p1u;
 147         *p1u++ = *p1l;
 148         *p1l++ = d;
 149       }
 150     }
 151     new_bm->off_y = new_bm->bbx_height - new_bm->off_y;
 152     new_bm->mv_y  = 0 - new_bm->mv_y;
 153   }
 154 
 155   if (o_mag_x < 0){
 156     p1 = new_bm->bitmap;
 157     for (y1 = 0; y1 < new_bm->bbx_height; y1++){
 158       for (x1 = 0; x1 < new_bm->bbx_width/2; x1++){
 159         x2 = new_bm->bbx_width - x1 - 1;
 160         d1 = (p1[x1/8] & scale_bit_table[x1%8]);
 161         d2 = (p1[x2/8] & scale_bit_table[x2%8]);
 162         p1[x1/8] = p1[x1/8] & ~scale_bit_table[x1%8];
 163         p1[x2/8] = p1[x2/8] & ~scale_bit_table[x2%8];
 164         if (d1 != 0)
 165           p1[x2/8] |= scale_bit_table[x2%8];
 166         if (d2 != 0)
 167           p1[x1/8] |= scale_bit_table[x1%8];
 168       }
 169       p1 = &p1[new_bm->raster];
 170     }
 171     new_bm->off_x = new_bm->off_x - new_bm->bbx_width;
 172     new_bm->mv_x  = 0 - new_bm->mv_x;
 173   }
 174 
 175   return new_bm;
 176 }
 177 
 178 
 179 /**
 180  ** VF_RotatedBitmap
 181  **/
 182 Public VF_BITMAP
 183 VF_RotatedBitmap(VF_BITMAP bm_src, int angle)
     /* [<][>][^][v][top][bottom][index][help] */
 184 {
 185   VF_BITMAP       bm_new;
 186   int             x, y, x2, y2;
 187   long            w, h;
 188   unsigned char  *p;
 189   static unsigned char  bits[] = 
 190     {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
 191 
 192   if ((bm_src == NULL) || (bm_src->bitmap == NULL))
 193     return NULL;
 194   w = bm_src->bbx_width;
 195   h = bm_src->bbx_height;
 196 
 197   bm_new = NULL;
 198   switch (angle){
 199   default:
 200     fprintf(stderr, 
 201             "VFlib: Unsupported rotation angle for VF_RotatedBitmap(): %d\n",
 202             angle);
 203     break;
 204 
 205   case VF_BM_ROTATE_0:
 206     bm_new = VF_CopyBitmap(bm_src);
 207     break;
 208 
 209   case VF_BM_ROTATE_90:
 210     bm_new = vf_alloc_bitmap(bm_src->bbx_height, bm_src->bbx_width);
 211     if (bm_new == NULL)
 212       return NULL;
 213     bm_new->off_x = bm_src->off_y;
 214     bm_new->off_y = bm_src->off_x + w;
 215     bm_new->mv_x = -bm_src->mv_y;
 216     bm_new->mv_y = bm_src->mv_x;
 217     for (y = 0; y < bm_src->bbx_height; y++){
 218       p = &bm_src->bitmap[y * bm_src->raster];
 219       for (x = 0; x < bm_src->bbx_width; x++){
 220         if ((bits[x%8] & p[x/8]) != 0){
 221           x2 = y;
 222           y2 = (w-1) - x;
 223           bm_new->bitmap[y2 * bm_new->raster + (x2/8)] |= bits[x2%8];
 224         }
 225       }
 226     }
 227     break;
 228 
 229   case VF_BM_ROTATE_180:
 230     bm_new = vf_alloc_bitmap(bm_src->bbx_width, bm_src->bbx_height);
 231     if (bm_new == NULL)
 232       return NULL;
 233     bm_new->off_x = -bm_src->off_x - w;
 234     bm_new->off_y = -bm_src->off_y + h;
 235     bm_new->mv_x = -bm_src->mv_x;
 236     bm_new->mv_y = -bm_src->mv_y;
 237     for (y = 0; y < bm_src->bbx_height; y++){
 238       p = &bm_src->bitmap[y * bm_src->raster];
 239       for (x = 0; x < bm_src->bbx_width; x++){
 240         if ((bits[x%8] & p[x/8]) != 0){
 241           x2 = (w-1) - x;
 242           y2 = (h-1) - y;
 243           bm_new->bitmap[y2 * bm_new->raster + (x2/8)] |= bits[x2%8];
 244         }
 245       }
 246     }
 247     break;
 248 
 249   case VF_BM_ROTATE_270:
 250     bm_new = vf_alloc_bitmap(bm_src->bbx_height, bm_src->bbx_width);
 251     if (bm_new  == NULL)
 252       return NULL;
 253     bm_new->off_x = bm_src->off_y - h;
 254     bm_new->off_y = -bm_src->off_x;
 255     bm_new->mv_x = bm_src->mv_y;
 256     bm_new->mv_y = -bm_src->mv_x;
 257     for (y = 0; y < bm_src->bbx_height; y++){
 258       p = &bm_src->bitmap[y * bm_src->raster];
 259       for (x = 0; x < bm_src->bbx_width; x++){
 260         if ((bits[x%8] & p[x/8]) != 0){
 261           x2 = (h-1) - y;
 262           y2 = x;
 263           bm_new->bitmap[y2 * bm_new->raster + (x2/8)] |= bits[x2%8];
 264         }
 265       }
 266     }
 267     break;
 268   }
 269   
 270   return bm_new;
 271 }
 272 
 273 
 274 /**
 275  ** VF_ReflectedBitmap
 276  **/
 277 Public VF_BITMAP
 278 VF_ReflectedBitmap(VF_BITMAP bm_src, int reflect_x, int reflect_y)
     /* [<][>][^][v][top][bottom][index][help] */
 279 {
 280   VF_BITMAP       bm_new;
 281   int             x, x8, y, x2, y2;
 282   long            w, h;
 283   unsigned char  *p_src, *p_new;
 284   static unsigned char  bits[] = 
 285     {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
 286 
 287   if ((bm_src == NULL) || (bm_src->bitmap == NULL))
 288     return NULL;
 289 
 290   if ((reflect_x == 0) && (reflect_y == 0))
 291     return VF_CopyBitmap(bm_src);
 292 
 293   w = bm_src->bbx_width;
 294   h = bm_src->bbx_height;
 295   if ((bm_new = vf_alloc_bitmap(w, h)) == NULL)
 296     return NULL;
 297 
 298   bm_new->off_x = bm_src->off_x;
 299   bm_new->off_y = bm_src->off_y;
 300   bm_new->mv_x  = bm_src->mv_x;
 301   bm_new->mv_y  = bm_src->mv_y;
 302 
 303   if ((reflect_x != 0) && (reflect_y == 0)){
 304     for (y = 0; y < h; y++){
 305       p_src = &bm_src->bitmap[bm_src->raster * y];
 306       p_new = &bm_new->bitmap[bm_new->raster * y];
 307       for (x = 0; x < w; x++){
 308         if ((bits[x % 8] & p_src[x / 8]) != 0){
 309           x2 = w - x - 1;
 310           p_new[x2 / 8] |= bits[x2 % 8];
 311         }
 312       }
 313     }
 314 
 315   } else if ((reflect_x == 0) && (reflect_y != 0)){ 
 316     for (y = 0; y < h; y++){
 317       p_src = &bm_src->bitmap[bm_src->raster * y];
 318       p_new = &bm_new->bitmap[bm_new->raster * (h - y - 1)];
 319       for (x8 = 0; x8 < (w+7)/8; x8++)
 320         *(p_new++) = *(p_src++);
 321     }
 322 
 323   } else /*if ((reflect_x != 0) && (reflect_x != 0))*/ { 
 324     for (y = 0; y < h; y++){
 325       y2 = h - y - 1;
 326       p_src = &bm_src->bitmap[bm_src->raster * y];
 327       p_new = &bm_new->bitmap[bm_new->raster * y2];
 328       for (x = 0; x < w; x++){
 329         if ((bits[x % 8] & p_src[x / 8]) != 0){
 330           x2 = w - x - 1;
 331           p_new[x2 / 8] |= bits[x2 % 8];
 332         }
 333       }
 334     }
 335     
 336   }
 337 
 338   return bm_new;
 339 }
 340 
 341 
 342 
 343 /**
 344  ** VF_CopyBitmap
 345  **/
 346 Public VF_BITMAP
 347 VF_CopyBitmap(VF_BITMAP bm_src)
     /* [<][>][^][v][top][bottom][index][help] */
 348 {
 349   VF_BITMAP  bm_new;
 350   int        h;
 351 
 352   vf_error = 0;
 353   ALLOC_IF_ERR(bm_new, struct vf_s_bitmap){
 354     vf_error = VF_ERR_NO_MEMORY;
 355     return NULL;
 356   }
 357   bm_new->bbx_width  = bm_src->bbx_width;
 358   bm_new->bbx_height = bm_src->bbx_height;
 359   bm_new->off_x   = bm_src->off_x;
 360   bm_new->off_y   = bm_src->off_y;
 361   bm_new->mv_x    = bm_src->mv_x;
 362   bm_new->mv_y    = bm_src->mv_y;
 363   bm_new->raster  = bm_src->raster;
 364   bm_new->bitmap  = (unsigned char*)malloc(bm_src->raster*bm_src->bbx_height);
 365 
 366   if (bm_new->bitmap == NULL){
 367     vf_free(bm_new);
 368     vf_error = VF_ERR_NO_MEMORY;
 369     return NULL;
 370   }
 371 
 372   for (h = 0; h < bm_src->bbx_height; h++){
 373     memcpy(&bm_new->bitmap[h * bm_new->raster], 
 374            &bm_src->bitmap[h * bm_src->raster], 
 375            bm_src->raster);
 376   }
 377   return bm_new;
 378 }
 379 
 380 
 381 /**
 382  ** VF_FillBitmap
 383  **/
 384 Public void
 385 VF_FillBitmap(VF_BITMAP bm)
     /* [<][>][^][v][top][bottom][index][help] */
 386 {
 387   int            xd, xm, xw, x, y;
 388   unsigned char  *p, *q;
 389   static unsigned char pix_tbl[] =
 390     {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
 391 
 392   if ((bm == NULL) || (bm->bitmap == NULL))
 393     return;
 394 
 395   xd = bm->bbx_width / 8;
 396   xm = bm->bbx_width % 8;
 397   p = bm->bitmap;
 398   for (x = 0; x < xd; x++)
 399     *(p++) = 0xff;
 400   if (xm != 0)
 401     *(p++) = pix_tbl[xm];
 402   xw = (bm->bbx_width + 7) / 8;
 403   for (y = bm->bbx_height-1; y > 0; --y){
 404     p = bm->bitmap;
 405     q = &bm->bitmap[bm->raster * y]; 
 406     for (x = xw; x > 0; --x)
 407       *(q++) = *(p++);
 408   }
 409 }
 410 
 411 
 412 /**
 413  ** VF_ClearBitmap
 414  **/
 415 Public void
 416 VF_ClearBitmap(VF_BITMAP bm)
     /* [<][>][^][v][top][bottom][index][help] */
 417 {
 418   int            xw, x, y;
 419   unsigned char  *p, *q;
 420 
 421   if ((bm == NULL) || (bm->bitmap == NULL))
 422     return;
 423 
 424   xw = (bm->bbx_width + 7) / 8;
 425   for (y = bm->bbx_height-1; y > 0; --y){
 426     p = bm->bitmap;
 427     q = &bm->bitmap[bm->raster * y]; 
 428     for (x = xw; x > 0; --x)
 429       *(q++) = *(p++);
 430   }
 431 }
 432 
 433 
 434 /**
 435  ** VF_MinimizeBitmap
 436  **/
 437 Public VF_BITMAP
 438 VF_MinimizeBitmap(VF_BITMAP bm_src)
     /* [<][>][^][v][top][bottom][index][help] */
 439 {
 440   VF_BITMAP      bm_new;
 441   int            yu, yl, xl, xr, y, x, xx, yy, w; 
 442   unsigned char  *p, *p0, *p1;
 443   Private unsigned char  bit_table[] = {
 444     0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
 445   };
 446 
 447   vf_error = 0;
 448   if ((bm_src == NULL) || (bm_src->bitmap == NULL))
 449     return NULL;
 450   
 451   /* find upper */
 452   yu = 0;
 453   y = 0;
 454   p0 = bm_src->bitmap;
 455   while (y < bm_src->bbx_height){
 456     p = p0;
 457     w = (bm_src->bbx_width+7)/8;
 458     for (x = 0; x < w; x++, p++){
 459       if (*p != 0){
 460         yu = y;
 461         goto bbx_found_upper;
 462       }
 463     }
 464     y++;
 465     p0 += bm_src->raster; 
 466   }
 467   goto Empty;
 468 
 469 bbx_found_upper:
 470   /* find lower */
 471   y = bm_src->bbx_height-1;
 472   p0 = &bm_src->bitmap[bm_src->raster * y];
 473   w = (bm_src->bbx_width+7)/8;
 474   while (y >= 0){
 475     p = p0;
 476     for (x = 0; x < w; x++, p++){
 477       if (*p != 0){
 478         yl = y;
 479         goto bbx_found_lower;
 480       }
 481     }
 482     --y;
 483     p0 -= bm_src->raster;
 484   }
 485   goto Empty;
 486 
 487 bbx_found_lower:  
 488   /* find left */
 489   xl = bm_src->bbx_width-1;
 490   p0 = &bm_src->bitmap[bm_src->raster * yu];
 491   for (y = yu; y <= yl; y++){
 492     p = p0;
 493     for (x = 0; x < xl; x++){
 494       if ((p[x/8] & bit_table[x%8]) != 0){
 495         xl = x;
 496         break;
 497       }
 498     }
 499     p0 += bm_src->raster;
 500   }
 501 
 502   /* find right */
 503   xr = 0;
 504   p0 = &bm_src->bitmap[bm_src->raster * yu];
 505   for (y = yu; y <= yl; y++){
 506     p = p0;
 507     for (x = bm_src->bbx_width-1; x > xr; --x){
 508       if ((p[x/8] & bit_table[x%8]) != 0){
 509         xr = x;
 510         break;
 511       }
 512     }
 513     p0 += bm_src->raster;
 514   }
 515 
 516   /**printf("** yu=%d yl=%d xl=%d xr=%d\n", yu, yl, xl, xr);**/
 517   if ((bm_new = vf_alloc_bitmap(xr - xl + 1, yl - yu + 1)) == NULL)
 518     return NULL;
 519   bm_new->off_x = bm_src->off_x + xl;
 520   bm_new->off_y = bm_src->off_y - yu;
 521   bm_new->mv_x  = bm_src->mv_x;
 522   bm_new->mv_y  = bm_src->mv_y;
 523   p0 = &bm_src->bitmap[bm_src->raster*yu];
 524   p1 = bm_new->bitmap;
 525   for (yy = 0; yy < bm_new->bbx_height; yy++){   /* SLOW! */
 526     for (xx = 0; xx < bm_new->bbx_width; xx++){  
 527       if ((p0[(xx+xl)/8] & bit_table[(xx+xl)%8]) != 0){
 528         p1[xx/8] |= bit_table[xx%8];
 529       }
 530     }
 531     p0 += bm_src->raster;
 532     p1 += bm_new->raster;
 533   }
 534   return bm_new;
 535 
 536 Empty:
 537   if ((bm_new = vf_alloc_bitmap(0, 0)) == NULL)
 538     return NULL;
 539   bm_new->off_x = 0;
 540   bm_new->off_y = 0;
 541   bm_new->mv_x  = bm_src->mv_x;
 542   bm_new->mv_y  = bm_src->mv_y;
 543   return bm_new;
 544 }
 545 
 546 
 547 Glocal VF_BITMAP
 548 vf_alloc_bitmap(int width, int height)
     /* [<][>][^][v][top][bottom][index][help] */
 549 {
 550   VF_BITMAP  bm_new;
 551   int        size, raster;
 552 
 553   ALLOC_IF_ERR(bm_new, struct vf_s_bitmap){
 554     vf_error = VF_ERR_NO_MEMORY;
 555     return NULL;
 556   }
 557   if (width == 0) 
 558     width = 1;
 559   if (height == 0)
 560     height = 1;
 561   raster = (width+7)/8;
 562   size = raster * height;
 563 
 564   bm_new->bbx_width  = width;
 565   bm_new->bbx_height = height;
 566   bm_new->raster     = raster;
 567   bm_new->off_x      = 0;
 568   bm_new->off_y      = height;
 569   bm_new->mv_x       = width;
 570   bm_new->mv_y       = 0;
 571   if ((bm_new->bitmap = (unsigned char*)malloc(size)) == NULL){
 572     vf_free(bm_new);
 573     vf_error = VF_ERR_NO_MEMORY;
 574     return NULL;
 575   }
 576   memclr(bm_new->bitmap, size);
 577   return bm_new;
 578 }
 579 
 580 Glocal VF_BITMAP
 581 vf_alloc_bitmap_with_metric1(VF_METRIC1 me, double dpi_x, double dpi_y)
     /* [<][>][^][v][top][bottom][index][help] */
 582 {
 583   int        size, raster, w, h;
 584   VF_BITMAP  bm_new;
 585 
 586   ALLOC_IF_ERR(bm_new, struct vf_s_bitmap){
 587     vf_error = VF_ERR_NO_MEMORY;
 588     return NULL;
 589   }
 590   
 591   if ((w = me->bbx_width  * (dpi_x / 72.27) + 0.5) == 0)
 592     w = 1;
 593   if ((h = me->bbx_height * (dpi_y / 72.27) + 0.5) == 0)
 594     h = 1;
 595   raster = (w+7)/8;
 596   size = raster * h;
 597 
 598   bm_new->bbx_width  = w;
 599   bm_new->bbx_height = h;
 600   bm_new->raster     = raster;
 601   bm_new->off_x      = me->off_x * (dpi_x / 72.27);
 602   bm_new->off_y      = me->off_y * (dpi_y / 72.27);
 603   bm_new->mv_x       = me->mv_x * (dpi_x / 72.27);
 604   bm_new->mv_y       = me->mv_y * (dpi_y / 72.27);
 605   if ((bm_new->bitmap = (unsigned char*)malloc(size)) == NULL){
 606     vf_free(bm_new);
 607     vf_error = VF_ERR_NO_MEMORY;
 608     return NULL;
 609   }
 610   memclr(bm_new->bitmap, size);
 611   return bm_new;
 612 }
 613 
 614 Glocal VF_BITMAP
 615 vf_alloc_bitmap_with_metric2(VF_METRIC2 met)
     /* [<][>][^][v][top][bottom][index][help] */
 616 {
 617   int        size, raster, w, h;
 618   VF_BITMAP  bm_new;
 619 
 620   ALLOC_IF_ERR(bm_new, struct vf_s_bitmap){
 621     vf_error = VF_ERR_NO_MEMORY;
 622     return NULL;
 623   }
 624 
 625   if ((w = met->bbx_width) == 0)
 626     w = 1;
 627   if ((h = met->bbx_height) == 0)
 628     h = 1;
 629   raster = (w + 7)/8;
 630   size = raster * h;
 631 
 632   bm_new->bbx_width  = w;
 633   bm_new->bbx_height = h;
 634   bm_new->raster     = raster;
 635   bm_new->off_x      = met->off_x;
 636   bm_new->off_y      = met->off_y;
 637   bm_new->mv_x       = met->mv_x;
 638   bm_new->mv_y       = met->mv_y;
 639   if ((bm_new->bitmap = (unsigned char*)malloc(size)) == NULL){
 640     vf_free(bm_new);
 641     vf_error = VF_ERR_NO_MEMORY;
 642     return NULL;
 643   }
 644   memclr(bm_new->bitmap, size);
 645   return bm_new;
 646 }
 647 
 648 
 649 /**
 650  **   VF_FreeBitmap
 651  **/
 652 Public void
 653 VF_FreeBitmap(VF_BITMAP vf_bitmap)
     /* [<][>][^][v][top][bottom][index][help] */
 654 {
 655   vf_error = 0;
 656   vf_free_bitmap(vf_bitmap);
 657 }
 658 
 659 Glocal void
 660 vf_free_bitmap(VF_BITMAP vf_bitmap)
     /* [<][>][^][v][top][bottom][index][help] */
 661 {
 662   if (vf_bitmap != NULL){
 663     vf_free(vf_bitmap->bitmap);
 664     vf_free(vf_bitmap);
 665   }
 666 }
 667 
 668 
 669 /**
 670  ** VF_DumpBitmap
 671  **/
 672 Public void
 673 VF_DumpBitmap(VF_BITMAP bm)
     /* [<][>][^][v][top][bottom][index][help] */
 674 {
 675   vf_error = 0;
 676   vf_dump_bitmap(bm);
 677 }
 678 
 679 Glocal void
 680 vf_dump_bitmap(VF_BITMAP bm)
     /* [<][>][^][v][top][bottom][index][help] */
 681 {
 682   unsigned char *p, *p0;
 683   int           x, y, x0, y0, x1, y1;
 684   int           ex;
 685   char          d2c[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
 686   static unsigned char bit_table[] = {
 687     0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
 688   };
 689 
 690   if ((bm == NULL) || ((p = bm->bitmap) == NULL))
 691     return;
 692 
 693   x0 = 0;
 694   if (bm->off_x > 0)
 695     x0 = -bm->off_x;
 696   y0 = 0;
 697   if (bm->off_y < 0)
 698     y0 = bm->off_y;
 699   x1 = bm->bbx_width;
 700   if (-bm->off_x > bm->bbx_width)
 701     x1 = -bm->off_x;
 702   y1 = bm->bbx_height;
 703   if (bm->off_y > bm->bbx_height)
 704     y1 = bm->off_y;
 705   if (-bm->off_x+bm->mv_x > x1)
 706     x1 = -bm->off_x+bm->mv_x;
 707   if (bm->off_y-bm->mv_y > y1)
 708     y1 = bm->off_y-bm->mv_y;
 709   ex = 1;
 710 
 711   putchar(' '); 
 712   for (x = x0-1-ex; x <= x1+1+ex; x++)
 713     printf("%c", d2c[((x % 10) + 10) % 10]);
 714   putchar('\n');
 715   putchar(' '); 
 716   putchar('+'); 
 717   for (x = x0-1-ex+1; x <= x1+1+ex-1; x++)
 718     putchar('-');
 719   putchar('+'); 
 720   putchar('\n');
 721   p0 = bm->bitmap;
 722   for (y = y0-ex; y < y1+ex; y++){
 723     if ((0 <= y) && (y <= bm->bbx_height))
 724       p = p0-1;
 725     printf("%c", d2c[((y % 10) + 10) % 10]);
 726     putchar('|');
 727     for (x = x0-ex; x <= x1+ex; x++){
 728       if ((0 <= x) && (x <= bm->bbx_width) && (x%8 == 0))
 729         p++;
 730       if ((x == -bm->off_x) && (y == bm->off_y)){
 731         if ((0 <= x) && (x < bm->bbx_width) 
 732             && (0 <= y) && (y < bm->bbx_height)
 733             && ((*p & bit_table[x%8]) != 0))
 734           putchar('+');
 735         else
 736           putchar('+');
 737       } else if ((x == (-bm->off_x + bm->mv_x))
 738                  && (y == (bm->off_y - bm->mv_y))){
 739         if ((*p & bit_table[x%8]) != 0)
 740           putchar('o');
 741         else
 742           putchar('o');
 743       } else if ((0 <= x) && (x < bm->bbx_width) 
 744                  && (0 <= y) && (y < bm->bbx_height)){
 745         if ((*p & bit_table[x%8]) != 0)
 746           putchar('@');
 747         else
 748           putchar('.');
 749       } else {
 750         putchar(' ');
 751       }
 752     }
 753     if ((0 <= y) && (y <= bm->bbx_height))
 754       p0 = p0 + bm->raster;
 755     putchar('|');
 756     printf("%c", d2c[((y % 10) + 10) % 10]);
 757     putchar('\n');
 758   }
 759   putchar(' '); 
 760   putchar('+'); 
 761   for (x = x0-1-ex+1; x <= x1+1+ex-1; x++)
 762     putchar('-');
 763   putchar('+'); 
 764   putchar('\n');
 765   putchar(' '); 
 766   for (x = x0-1-ex; x <= x1+1+ex; x++)
 767     printf("%c", d2c[((x % 10) + 10) % 10]);
 768   putchar('\n');
 769 }
 770 
 771 /*EOF*/

/* [<][>][^][v][top][bottom][index][help] */