changes that makes the bitmap loading algorithm more robust.
[neuro.git] / src / misc / bitmap.c
blob8481adde80fb1b339ce71d3594e153ac57b7dab5
2 /*
3 * libneuro, a light weight abstraction of high or lower libraries
4 * and toolkit for applications.
5 * Copyright (C) 2005-2006 Nicholas Niro, Robert Lemay
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 /* bitmap.c
23 * Module : Bitmap
25 * bitmap process module
28 /* the package's main config file */
29 #include <config.h>
31 /*-------------------- Extern Headers Including --------------------*/
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <math.h>
35 #include <string.h>
37 #if USE_ZLIB 1
38 /* this is used to open the bitmaps,
39 * the beauty of this is it works
40 * for compressed and uncompressed
41 * transparently, meaning no extra code
42 * for both!
44 #include <zlib.h>
45 typedef gzFile nFILE;
46 #else /* NOT USE_ZLIB */
47 typedef FILE nFILE;
48 #endif /* USE_ZLIB */
50 /*-------------------- Local Headers Including ---------------------*/
51 #include <ebuf.h>
52 #include <other.h>
53 #include <extlib.h> /* Lib_GetDefaultDepth() */
55 #include <graphics.h> /* Neuro_PutPixel */
57 /*-------------------- Main Module Header --------------------------*/
58 #include <bitmap.h>
60 /*-------------------- Other ----------------------------*/
62 NEURO_MODULE_CHANNEL("bitmap");
64 typedef struct BITMAP_HEADER
66 u16 type __attribute__((packed)); /* Magic identifier */
67 u32 size __attribute__((packed)); /* File size in bytes */
68 u16 reserved1, reserved2; /* reserved */
69 u32 offset __attribute__((packed)); /* Offset to image data, bytes */
70 }BITMAP_HEADER;
72 typedef struct BITMAP_INFOHEADER
74 u32 size; /* Header size in bytes */
75 i32 width, height; /* Width and height of image */
76 u16 planes; /* Number of colour planes */
77 u16 bits; /* Bits per pixel */
78 u32 compression; /* Compression type */
79 u32 imagesize; /* Image size in bytes */
80 i32 xresolution, yresolution; /* Pixels per meter */
81 u32 ncolors; /* Number of colours */
82 u32 importantcolours; /* Important colours */
83 }BITMAP_INFOHEADER;
85 typedef struct BITMAP_HDATA
87 BITMAP_HEADER header __attribute__((packed));
88 BITMAP_INFOHEADER infoheader __attribute__((packed));
89 }BITMAP_HDATA;
91 typedef struct BITMAP_COLOR
93 u8 r, g, b /*, a*/ ; /* red green blue */
94 }BITMAP_COLOR;
96 typedef struct BITMAP_MAP
98 BITMAP_COLOR *color;
99 }BITMAP_MAP;
101 struct BMP_CTX
103 nFILE *f_bitmap;
105 /* major (buffers) */
106 EBUF *bmap_colors; /* the colors */
107 u8 *buf; /* the buffer that will contain the content of the file */
109 /* minor (mostly pointers and temporary variables) */
110 i32 i; /* incremental variable */
111 u32 skip_i, x, y;
113 u32 psize; /* the full size of the pixels data */
114 u8 *palette; /* the pointer to the palette if theres one */
115 BITMAP_HDATA *bmap; /* this is how we will get informations about the bitmap */
116 int aux_var; /* auxiliary variable that can be used by external functions */
117 char *aux_buf; /* same as aux_var but a buffer */
118 double msize;
119 double calc;
120 double tmp;
121 u32 wmult;
122 double pixellen;
123 u32 increm;
124 u8 DATA;
125 v_object *output; /* the image into which we will load the bitmap */
129 /*-------------------- Global Variables ----------------------------*/
131 /*-------------------- Static Variables ----------------------------*/
133 /*-------------------- Static Prototypes ---------------------------*/
135 static void print_bitmap_infos(BITMAP_HDATA *bmap) __attribute__((unused));
136 static int fpdata8(nFILE *input, u8 *output) __attribute__((unused));
137 static int fpdata16(nFILE *input, u16 *output) __attribute__((unused));
138 static int fpdata32(nFILE *input, u32 *output) __attribute__((unused));
141 /*-------------------- Static Functions ----------------------------*/
143 static void
144 clean_bmap_color(void *eng)
146 BITMAP_COLOR *buf;
148 buf = (BITMAP_COLOR*)eng;
152 /* returns 0 on success and puts the data in *output
153 * 1 on error dont touch output
155 static int
156 fpdata8(nFILE *input, u8 *output)
158 if (input == NULL || output == NULL)
159 return 1;
160 #if USE_ZLIB 1
161 *output = gzgetc(input);
162 #else /* NOT USE_ZLIB */
163 *output = fgetc(input);
164 #endif /* NOT USE_ZLIB */
167 return 0;
170 /* returns 0 on success and puts the data in *output
171 * 1 on error dont touch output
173 static int
174 fpdata16(nFILE *input, u16 *output)
176 u8 feed[2];
177 u16 *buf;
178 u16 temp = 0;
180 if (input == NULL || output == NULL)
181 return 1;
182 #if temp
183 #if USE_ZLIB 1
184 feed[0] = gzgetc(input);
185 feed[1] = gzgetc(input);
186 #else /* NOT USE_ZLIB */
187 feed[0] = fgetc(input);
188 feed[1] = fgetc(input);
189 #endif /* NOT USE_ZLIB */
191 buf = (u16*)&feed;
193 *output = *buf;
195 #endif /* temp */
197 temp = gzgetc(input);
198 temp <<= 8;
199 temp += gzgetc(input);
201 *output = temp;
203 return 0;
206 /* returns 0 on success and puts the data in *output
207 * 1 on error dont touch output
209 static int
210 fpdata32(nFILE *input, u32 *output)
212 /* register int feed; */
213 u8 feed[4];
214 u32 *buf;
217 if (input == NULL || output == NULL)
218 return 1;
220 #if USE_ZLIB 1
221 feed[0] = gzgetc(input);
222 feed[1] = gzgetc(input);
223 feed[2] = gzgetc(input);
224 feed[3] = gzgetc(input);
225 #else /* NOT USE_ZLIB */
226 feed[0] = fgetc(input);
227 feed[1] = fgetc(input);
228 feed[2] = fgetc(input);
229 feed[3] = fgetc(input);
230 #endif /* NOT USE_ZLIB */
232 buf = (u32*)&feed;
234 *output = *buf;
236 return 0;
239 static BITMAP_HDATA *
240 parse_bitmap_header(nFILE *input)
242 BITMAP_HDATA *buf;
243 BITMAP_INFOHEADER *tmp;
245 if (input == NULL)
246 return NULL;
248 buf = calloc(1, sizeof(BITMAP_HDATA));
250 tmp = &buf->infoheader;
252 fpdata16(input, &buf->header.type);
253 fpdata32(input, &buf->header.size);
254 fpdata16(input, &buf->header.reserved1);
255 fpdata16(input, &buf->header.reserved2);
256 fpdata32(input, &buf->header.offset);
258 fpdata32(input, &tmp->size);
259 fpdata32(input, (u32*)&tmp->width);
260 fpdata32(input, (u32*)&tmp->height);
261 fpdata16(input, &tmp->planes);
262 fpdata16(input, &tmp->bits);
263 fpdata32(input, &tmp->compression);
264 fpdata32(input, &tmp->imagesize);
265 fpdata32(input, (u32*)&tmp->xresolution);
266 fpdata32(input, (u32*)&tmp->yresolution);
267 fpdata32(input, &tmp->ncolors);
268 fpdata32(input, &tmp->importantcolours);
270 return buf;
273 /* the magic number will probably not show correctly if big endian */
274 static void
275 print_bitmap_infos(BITMAP_HDATA *bmap)
277 printf("(0x%x)[%c%c] header data :\nsize %d\noffset %d\ninfoheader data :\nsize %d\nwidth %d\nheight %d\nplanes %d\nbits %d\ncompression %d\nimagesize %d\nxres %d\nyres %d\nncolors %d\nimportantcolors %d\n",
278 bmap->header.type,
279 bmap->header.type & 0x00FF,
280 (bmap->header.type & 0xFF00) >> 8,
281 bmap->header.size,
282 bmap->header.offset,
283 bmap->infoheader.size,
284 bmap->infoheader.width,
285 bmap->infoheader.height,
286 bmap->infoheader.planes,
287 bmap->infoheader.bits,
288 bmap->infoheader.compression,
289 bmap->infoheader.imagesize,
290 bmap->infoheader.xresolution,
291 bmap->infoheader.yresolution,
292 bmap->infoheader.ncolors,
293 bmap->infoheader.importantcolours);
297 static void
298 process_palette(nFILE *input, BITMAP_HDATA *bmap, EBUF *bcolors)
300 u32 i = 0;
301 BITMAP_COLOR *buf;
303 while (i < bmap->infoheader.ncolors)
305 Neuro_AllocEBuf(bcolors, sizeof(BITMAP_COLOR*), sizeof(BITMAP_COLOR));
307 buf = Neuro_GiveCurEBuf(bcolors);
309 /*buf->r = palette[(i * 4) + 2];
310 buf->g = palette[(i * 4) + 1];
311 buf->b = palette[(i * 4)];
315 fpdata8(input, &buf->b);
316 fpdata8(input, &buf->g);
317 fpdata8(input, &buf->r);
318 fpdata8(input, &buf->a);
320 #if USE_ZLIB 1
321 buf->b = gzgetc(input);
322 buf->g = gzgetc(input);
323 buf->r = gzgetc(input);
325 /* I leave this just in case */
326 /* buf->a = fgetc(input); */
328 /* skip the alpha color */
329 gzgetc(input);
330 #else /* NOT USE_ZLIB */
331 buf->b = fgetc(input);
332 buf->g = fgetc(input);
333 buf->r = fgetc(input);
335 /* I leave this just in case */
336 /* buf->a = fgetc(input); */
338 /* skip the alpha color */
339 fgetc(input);
340 #endif /* NOT USE_ZLIB */
341 i++;
345 /* input the bits per pixel of the image
346 * input a 1 byte of data to process
348 static void
349 process_bitmap2(BITMAP_HDATA *bmap, v_object *image, u8 *palette, u8 *data, EBUF *bcolors, u32 *x, u32 *y, int *aux, char **buf)
352 /* we will call functions depending on the bpp of the image */
353 switch (bmap->infoheader.bits)
355 case 1:
357 /* will do a loop to get each 8 pixels from the data */
359 /* this is pretty much for little endian
360 * the minimum data size we can have for a certain width is
361 * 32 bits (4 bytes increments). Those 32 bits will be able
362 * to hold up to 32 pixels. In case the width is higher than
363 * 32 pixels, it will put 32 bits until the whole width
364 * can be fulfilled.
366 /* we will need to have the width value because we will need
367 * to know how many bits we have to read from 32 bits (4 bytes).
369 /* aux will keep how many 32 bits still need to be done in a
370 * certain width
372 u8 temp;
373 /* double calc = 0; */
375 /* u8 r, g, b; */
377 const u8 values[8] = {
378 0x80,
379 0x40,
380 0x20,
381 0x10,
382 0x08,
383 0x04,
384 0x02,
385 0x01
387 u32 i = 0;
388 u32 max = 0;
390 if (*buf == NULL)
392 *buf = calloc(1, sizeof(char));
393 **buf = 0;
394 *aux = 0;
397 /* set up aux for remaining pixels */
398 if (*aux == 0)
399 *aux = bmap->infoheader.width;
401 /* set up the number of pixels we need to process in this cycle */
402 if (*aux > 8)
404 max = 8;
405 *aux = *aux - 8;
407 else
409 max = *aux;
410 *aux = 0;
413 temp = *data;
415 while (i < max)
417 BITMAP_COLOR *cbuf = NULL;
419 if (IsLittleEndian())
420 temp = *data & values[i];
421 else
422 temp = *data & values[7 - i];
425 if (temp)
426 temp = 1;
428 cbuf = Neuro_GiveEBuf(bcolors, temp);
430 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->r, cbuf->g, cbuf->b));
432 *x = *x + 1;
433 i++;
436 if (*x > bmap->infoheader.width - 1)
438 *x = 0;
439 *y = *y + 1;
442 break;
444 case 4:
446 /* will do a loop to get each 2 pixels from the data */
447 u8 temp;
448 /* double calc = 0; */
450 /* u8 r, g, b; */
452 const u8 values[2] = {
453 0xF0,
454 0x0F,
456 u32 i = 0;
457 u32 max = 0;
459 if (*buf == NULL)
461 *buf = calloc(1, sizeof(char));
462 **buf = 0;
463 *aux = 0;
466 /* set up aux for remaining pixels */
467 if (*aux == 0)
468 *aux = bmap->infoheader.width;
470 /* set up the number of pixels we need to process in this cycle */
471 if (*aux > 2)
473 max = 2;
474 *aux = *aux - 2;
476 else
478 max = *aux;
479 *aux = 0;
482 temp = *data;
484 while (i < max)
486 BITMAP_COLOR *cbuf = NULL;
488 if (IsLittleEndian())
490 temp = *data & values[i];
492 if (temp > values[1])
493 temp >>= 4;
495 else
497 temp = *data & values[1 - i];
499 if (temp > values[0])
500 temp <<= 4;
503 cbuf = Neuro_GiveEBuf(bcolors, temp);
505 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->r, cbuf->g, cbuf->b));
507 *x = *x + 1;
508 i++;
511 if (*x > bmap->infoheader.width - 1)
513 *x = 0;
514 *y = *y + 1;
518 break;
520 case 8:
522 /* will get the single pixel from the data */
523 u8 temp;
524 /* double calc = 0; */
526 /* u8 r, g, b; */
528 u32 i = 0;
529 u32 max = 0;
531 if (*buf == NULL)
533 *buf = calloc(1, sizeof(char));
534 **buf = 0;
535 *aux = 0;
538 /* set up aux for remaining pixels */
539 if (*aux == 0)
540 *aux = bmap->infoheader.width;
542 /* set up the number of pixels we need to process in this cycle */
543 if (*aux > 1)
545 max = 1;
546 *aux = *aux - 1;
548 else
550 max = *aux;
551 *aux = 0;
554 temp = *data;
556 while (i < max)
558 BITMAP_COLOR *cbuf = NULL;
559 temp = *data;
562 cbuf = Neuro_GiveEBuf(bcolors, temp);
564 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->r, cbuf->g, cbuf->b));
566 *x = *x + 1;
567 i++;
570 if (*x > bmap->infoheader.width - 1)
572 *x = 0;
573 *y = *y + 1;
577 break;
579 case 16:
581 /* we do not support 16 bit because I think they
582 * use 24 bit for those. we'll see through use.
583 * if not, I really think this depth is pointless...
586 break;
588 case 24:
590 /* will need to gather the data for 2 other bytes to get a
591 * single pixel. We will use the auxiliary variable to keep
592 * track of where we are at in the gathering.
595 if (!*buf)
597 *buf = calloc(3, sizeof(u8));
598 *aux = 0;
601 (*buf)[*aux] = *data;
602 *aux = *aux + 1;
604 if (*aux >= 3)
606 *aux = 0;
608 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB((*buf)[2], (*buf)[1], (*buf)[0]));
610 *x = *x + 1;
613 if (*x > bmap->infoheader.width - 1)
615 *x = 0;
616 *y = *y + 1;
619 break;
621 case 32:
623 /* we do not support 32 bit because it is Very uncommon if it
624 * actually exist. Pretty much the same as 16 bpp.
627 break;
629 default:
631 /* an error occured */
633 break;
638 static i8
639 processGradual_BMP(BMP_CTX *ctx, u32 loops)
641 if (ctx == NULL)
643 NEURO_WARN("argument ctx is NULL", NULL);
644 return -1;
647 if (ctx->f_bitmap == NULL)
649 NEURO_WARN("bitmap file descriptor is NULL", NULL);
650 return -1;
653 if (ctx->i == 0)
655 ctx->bmap = parse_bitmap_header(ctx->f_bitmap);
657 /* TODO TODO XXX check here if the bitmap is valid or not
658 * first check for the BM word
659 * then we check for the size of the file in header and size
660 * we got when reading the file
663 print_bitmap_infos(ctx->bmap);
665 if (ctx->bmap->header.type != 0x424d)
667 NEURO_WARN("Invalid bitmap file", NULL);
668 return -1;
674 /* if it is valid, we create the buffers */
675 Neuro_CreateEBuf(&ctx->bmap_colors);
676 Neuro_SetcallbEBuf(ctx->bmap_colors, &clean_bmap_color);
679 /* print_bitmap_infos(bmap); */
681 /* process the bitmap(load it in memory) */
682 ctx->i = 0;
683 ctx->psize = ctx->bmap->header.size - (sizeof(BITMAP_HEADER) + sizeof(BITMAP_INFOHEADER));
684 ctx->psize = ctx->psize - (ctx->bmap->infoheader.ncolors * 4);
685 /* printf("data size %d\n", psize); */
687 printf("ncolors : %d\n", ctx->bmap->infoheader.ncolors);
689 return -1;
691 if (ctx->bmap->infoheader.ncolors > 0)
693 process_palette(ctx->f_bitmap, ctx->bmap, ctx->bmap_colors);
696 printf("herein\n");
697 return -1;
699 /* we create the v_object
701 * will need to put better values for the masks to support SDL.
704 u32 rmask = 0, gmask = 0, bmask = 0, amask = 0;
706 if (IsLittleEndian())
708 switch (ctx->bmap->infoheader.bits)
710 case 8:
712 rmask = 0x000000C0;
713 gmask = 0x0000003C;
714 bmask = 0x00000003;
715 amask = 0x00000000;
717 break;
719 case 16:
721 rmask = 0x0000f800;
722 gmask = 0x000007e0;
723 bmask = 0x0000001f;
724 amask = 0x00000000;
726 break;
728 case 24:
730 rmask = 0x00ff0000;
731 gmask = 0x0000ff00;
732 bmask = 0x000000ff;
733 amask = 0x00000000;
735 break;
738 default:
739 break;
742 else
744 switch (ctx->bmap->infoheader.bits)
746 case 8:
748 rmask = 0x00000003;
749 gmask = 0x0000003C;
750 bmask = 0x000000C0;
751 amask = 0x00000000;
753 break;
755 case 16:
757 rmask = 0x0000001f;
758 gmask = 0x000007e0;
759 bmask = 0x0000f800;
760 amask = 0x00000000;
762 break;
764 case 24:
766 rmask = 0x0000ff00;
767 gmask = 0x00ff0000;
768 bmask = 0xff000000;
769 amask = 0x00000000;
771 break;
773 default:
774 break;
778 ctx->output = Neuro_CreateVObject(0, ctx->bmap->infoheader.width, ctx->bmap->infoheader.height, ctx->bmap->infoheader.bits, rmask, gmask, bmask, amask);
780 if (ctx->output == NULL)
782 NEURO_WARN("Created output v_object is NULL", NULL);
783 return -1;
787 /* semi static values to skip bytes that form 32 bit chunks in the data */
789 ctx->pixellen = (8 / (double)ctx->bmap->infoheader.bits);
790 ctx->msize = ctx->pixellen * 4;
792 /* we calculate the number of bytes there is per rows
793 * this is mainly so we can know how much "alignment"
794 * bytes there is (which need to be skipped)
797 ctx->wmult = (u32)ctx->bmap->infoheader.bits / 8;
799 if (ctx->wmult == 0)
800 ctx->wmult++;
802 ctx->wmult = ctx->wmult * ctx->bmap->infoheader.width;
805 ctx->increm = (u32)ctx->pixellen;
807 if (ctx->increm == 0)
808 ctx->increm++;
810 ctx->x = (u32)(ctx->bmap->infoheader.width / ctx->msize);
811 ctx->tmp = ctx->msize * ctx->x;
812 ctx->tmp = (double)ctx->bmap->infoheader.width - ctx->tmp;
813 ctx->tmp = ctx->tmp - 0.000001; /* to avoid bugs */
815 ctx->x = 0;
816 #if USE_ZLIB 1
817 gzseek(ctx->f_bitmap, ctx->bmap->header.offset, SEEK_SET);
818 #else /* NOT USE_ZLIB */
819 fseek(ctx->f_bitmap, ctx->bmap->header.offset, SEEK_SET);
820 #endif /* NOT USE_ZLIB */
822 } /* if i == 0 */
823 /* else */ /* if i != 0 */
825 i32 initial = ctx->i;
827 Lib_LockVObject(ctx->output);
831 /* while (ctx->i < ctx->psize) */
832 while (ctx->i < (initial + loops))
834 if (ctx->tmp > 0)
836 /* skip bytes that are inside the bitmap for
837 * filling purpose. (the data is purposely filled
838 * with 0 bits so the data is 32bits aligned)
840 if (ctx->skip_i >= ctx->wmult)
842 ctx->calc = ctx->tmp / ctx->pixellen;
843 ctx->skip_i = (u32)ctx->calc;
844 if (ctx->skip_i < ctx->calc)
846 ctx->skip_i++;
848 ctx->skip_i = (4 - ctx->skip_i);
849 ctx->i += ctx->skip_i;
851 #if USE_ZLIB 1
852 gzseek(ctx->f_bitmap, ctx->bmap->header.offset + ctx->i, SEEK_SET);
853 #else /* NOT USE_ZLIB */
854 fseek(ctx->f_bitmap, ctx->bmap->header.offset + ctx->i, SEEK_SET);
855 #endif /* NOT USE_ZLIB */
858 printf("skipping %d bytes wmult %d width %d tmp %f plen %f calc %f\n",
859 skip_i,
860 wmult,
861 bmap->infoheader.width,
862 tmp,
863 pixellen, calc);
866 ctx->skip_i = 0;
869 ctx->skip_i += ctx->increm;
871 if (ctx->i >= ctx->psize)
872 break;
876 fpdata8(ctx->f_bitmap, &ctx->DATA);
878 process_bitmap2(ctx->bmap, ctx->output, ctx->palette, &ctx->DATA,
879 ctx->bmap_colors, &ctx->x, &ctx->y, &ctx->aux_var, &ctx->aux_buf);
881 ctx->i++;
884 Lib_UnlockVObject(ctx->output);
888 if (ctx->i >= ctx->psize)
889 { /* this bitmap finished being loaded, we free everything */
891 /* to prevent further calls to be processed */
892 ctx->i = -1;
894 if (ctx->bmap)
895 free(ctx->bmap);
896 if (ctx->buf)
897 free(ctx->buf);
898 if (ctx->aux_buf)
899 free(ctx->aux_buf);
901 Neuro_CleanEBuf(&ctx->bmap_colors);
903 #if USE_ZLIB 1
904 if (ctx->f_bitmap)
905 gzclose(ctx->f_bitmap);
906 #else /* NOT USE_ZLIB */
907 if (ctx->f_bitmap)
908 fclose(ctx->f_bitmap);
909 #endif /* NOT USE_ZLIB */
911 return 100;
914 /*Debug_Val(0, "((%d * 100) / %d) == %d\n",
915 ctx->i, ctx->psize,
916 (i8)((u32)((ctx->i * 100) / ctx->psize)));*/
918 return (i8)((u32)(ctx->i * 100) / ctx->psize);
921 /* this never happens unless the image was already loaded */
922 NEURO_TRACE("Useless call of the function #%d", ctx->i);
923 return -1;
926 /*-------------------- Global Functions ----------------------------*/
928 v_object *
929 readBitmapFile(const char *bitmap)
931 BMP_CTX *ctx = NULL;
932 int _err = 0;
934 ctx = Bitmap_CreateCTX(bitmap);
936 if (ctx == NULL)
938 NEURO_WARN("Context creation failed", NULL);
939 return NULL;
942 while (1 != 2)
944 _err = Bitmap_Poll(ctx);
946 if (_err == 100)
947 break;
949 if (_err < 0)
951 NEURO_WARN("Poll failed...", NULL);
952 return NULL;
955 printf("loading progress : %d\n", _err);
958 return Bitmap_DestroyCTX(ctx);
961 /*-------------------- Poll ----------------------------------------*/
963 /* returns a percentage of progress */
965 Bitmap_Poll(BMP_CTX *ctx)
967 return processGradual_BMP(ctx, 512);
970 /*-------------------- Constructor Destructor ----------------------*/
972 BMP_CTX *
973 Bitmap_CreateCTX(const char *path)
975 BMP_CTX *output;
977 output = calloc(1, sizeof(BMP_CTX));
979 if (output == NULL)
980 return NULL;
981 #if USE_ZLIB 1
982 output = gzopen(path, "r"); /* can also be used for non compressed files */
983 #else /* NOT USE_ZLIB */
984 output = fopen(path, "r");
985 #endif /* NOT USE_ZLIB */
987 if (output->f_bitmap == NULL)
989 free(output);
990 return NULL;
993 return output;
996 v_object *
997 Bitmap_DestroyCTX(BMP_CTX *ctx)
999 v_object *output = NULL;
1001 if (ctx == NULL)
1002 return NULL;
1004 output = ctx->output;
1006 free(ctx);
1008 return output;