src/bitmap.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_MakeScaledBitmap
- VF_RotatedBitmap
- VF_ReflectedBitmap
- VF_CopyBitmap
- VF_FillBitmap
- VF_ClearBitmap
- VF_MinimizeBitmap
- vf_alloc_bitmap
- vf_alloc_bitmap_with_metric1
- vf_alloc_bitmap_with_metric2
- VF_FreeBitmap
- vf_free_bitmap
- VF_DumpBitmap
- 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*/