Disabled the debugging functions temporarily.
[neuro.git] / src / misc / bitmap.c
blob7aec534448dc0f1c73b1b5ce98436534be9d4113
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 <global.h>
52 #include <ebuf.h>
53 #include <other.h>
54 #include <extlib.h> /* Lib_GetDefaultDepth() */
56 #include <graphics.h> /* Neuro_PutPixel */
58 /*-------------------- Main Module Header --------------------------*/
59 #include <bitmap.h>
61 /*-------------------- Other ----------------------------*/
63 NEURO_MODULE_CHANNEL("bitmap");
65 typedef struct BITMAP_HEADER
67 u16 type __attribute__((packed)); /* Magic identifier */
68 u32 size __attribute__((packed)); /* File size in bytes */
69 u16 reserved1, reserved2; /* reserved */
70 u32 offset __attribute__((packed)); /* Offset to image data, bytes */
71 }BITMAP_HEADER;
73 typedef struct BITMAP_INFOHEADER
75 u32 size; /* Header size in bytes */
76 i32 width, height; /* Width and height of image */
77 u16 planes; /* Number of colour planes */
78 u16 bits; /* Bits per pixel */
79 u32 compression; /* Compression type */
80 u32 imagesize; /* Image size in bytes */
81 i32 xresolution, yresolution; /* Pixels per meter */
82 u32 ncolors; /* Number of colours */
83 u32 importantcolours; /* Important colours */
84 }BITMAP_INFOHEADER;
86 typedef struct BITMAP_HDATA
88 BITMAP_HEADER header __attribute__((packed));
89 BITMAP_INFOHEADER infoheader __attribute__((packed));
90 }BITMAP_HDATA;
92 typedef struct BITMAP_COLOR
94 u8 r, g, b /*, a*/ ; /* red green blue */
95 }BITMAP_COLOR;
97 typedef struct BITMAP_MAP
99 BITMAP_COLOR *color;
100 }BITMAP_MAP;
102 struct BMP_CTX
104 nFILE *f_bitmap;
106 /* major (buffers) */
107 EBUF *bmap_colors; /* the colors */
108 u8 *buf; /* the buffer that will contain the content of the file */
110 /* minor (mostly pointers and temporary variables) */
111 i32 i; /* incremental variable */
112 u32 skip_i, x, y;
114 u32 psize; /* the full size of the pixels data */
115 u8 *palette; /* the pointer to the palette if theres one */
116 BITMAP_HDATA *bmap; /* this is how we will get informations about the bitmap */
117 int aux_var; /* auxiliary variable that can be used by external functions */
118 char *aux_buf; /* same as aux_var but a buffer */
119 double msize;
120 double calc;
121 double tmp;
122 u32 wmult;
123 double pixellen;
124 u32 increm;
125 u8 DATA;
126 v_object *output; /* the image into which we will load the bitmap */
127 u32 cut_size; /* amount of bytes to load per cycles */
131 /*-------------------- Global Variables ----------------------------*/
133 /*-------------------- Static Variables ----------------------------*/
135 /*-------------------- Static Prototypes ---------------------------*/
137 static void print_bitmap_infos(BITMAP_HDATA *bmap) __attribute__((unused));
138 static int fpdata8(nFILE *input, u8 *output) __attribute__((unused));
139 static int fpdata16(nFILE *input, u16 *output) __attribute__((unused));
140 static int fpdata32(nFILE *input, u32 *output) __attribute__((unused));
143 /*-------------------- Static Functions ----------------------------*/
145 static void
146 clean_bmap_color(void *eng)
148 BITMAP_COLOR *buf;
150 buf = (BITMAP_COLOR*)eng;
154 /* returns 0 on success and puts the data in *output
155 * 1 on error dont touch output
157 static int
158 fpdata8(nFILE *input, u8 *output)
160 if (input == NULL || output == NULL)
161 return 1;
162 #if USE_ZLIB 1
163 *output = gzgetc(input);
164 #else /* NOT USE_ZLIB */
165 *output = fgetc(input);
166 #endif /* NOT USE_ZLIB */
169 return 0;
172 /* returns 0 on success and puts the data in *output
173 * 1 on error dont touch output
175 static int
176 fpdata16(nFILE *input, u16 *output)
178 u8 feed[2];
179 u16 *buf;
181 if (input == NULL || output == NULL)
182 return 1;
184 if (IsLittleEndian())
186 #if USE_ZLIB 1
187 feed[0] = gzgetc(input);
188 feed[1] = gzgetc(input);
189 #else /* NOT USE_ZLIB */
190 feed[0] = fgetc(input);
191 feed[1] = fgetc(input);
192 #endif /* NOT USE_ZLIB */
194 else
196 feed[1] = gzgetc(input);
197 feed[0] = gzgetc(input);
200 buf = (u16*)&feed;
202 *output = *buf;
204 return 0;
207 /* returns 0 on success and puts the data in *output
208 * 1 on error dont touch output
210 static int
211 fpdata32(nFILE *input, u32 *output)
213 /* register int feed; */
214 u8 feed[4];
215 u32 *buf;
218 if (input == NULL || output == NULL)
219 return 1;
221 if (IsLittleEndian())
223 #if USE_ZLIB 1
224 feed[0] = gzgetc(input);
225 feed[1] = gzgetc(input);
226 feed[2] = gzgetc(input);
227 feed[3] = gzgetc(input);
228 #else /* NOT USE_ZLIB */
229 feed[0] = fgetc(input);
230 feed[1] = fgetc(input);
231 feed[2] = fgetc(input);
232 feed[3] = fgetc(input);
233 #endif /* NOT USE_ZLIB */
235 else
237 feed[3] = gzgetc(input);
238 feed[2] = gzgetc(input);
239 feed[1] = gzgetc(input);
240 feed[0] = gzgetc(input);
243 buf = (u32*)&feed;
245 *output = *buf;
247 return 0;
250 static BITMAP_HDATA *
251 parse_bitmap_header(nFILE *input)
253 BITMAP_HDATA *buf;
254 BITMAP_INFOHEADER *tmp;
256 if (input == NULL)
257 return NULL;
259 buf = calloc(1, sizeof(BITMAP_HDATA));
261 tmp = &buf->infoheader;
263 fpdata16(input, &buf->header.type);
264 fpdata32(input, &buf->header.size);
265 fpdata16(input, &buf->header.reserved1);
266 fpdata16(input, &buf->header.reserved2);
267 fpdata32(input, &buf->header.offset);
269 fpdata32(input, &tmp->size);
270 fpdata32(input, (u32*)&tmp->width);
271 fpdata32(input, (u32*)&tmp->height);
272 fpdata16(input, &tmp->planes);
273 fpdata16(input, &tmp->bits);
274 fpdata32(input, &tmp->compression);
275 fpdata32(input, &tmp->imagesize);
276 fpdata32(input, (u32*)&tmp->xresolution);
277 fpdata32(input, (u32*)&tmp->yresolution);
278 fpdata32(input, &tmp->ncolors);
279 fpdata32(input, &tmp->importantcolours);
281 return buf;
284 /* the magic number will probably not show correctly if big endian */
285 static void
286 print_bitmap_infos(BITMAP_HDATA *bmap)
288 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",
289 bmap->header.type,
290 bmap->header.type & 0x00FF,
291 (bmap->header.type & 0xFF00) >> 8,
292 bmap->header.size,
293 bmap->header.offset,
294 bmap->infoheader.size,
295 bmap->infoheader.width,
296 bmap->infoheader.height,
297 bmap->infoheader.planes,
298 bmap->infoheader.bits,
299 bmap->infoheader.compression,
300 bmap->infoheader.imagesize,
301 bmap->infoheader.xresolution,
302 bmap->infoheader.yresolution,
303 bmap->infoheader.ncolors,
304 bmap->infoheader.importantcolours);
308 static void
309 process_palette(nFILE *input, BITMAP_HDATA *bmap, EBUF *bcolors)
311 u32 i = 0;
312 BITMAP_COLOR *buf;
314 while (i < bmap->infoheader.ncolors)
316 Neuro_AllocEBuf(bcolors, sizeof(BITMAP_COLOR*), sizeof(BITMAP_COLOR));
318 buf = Neuro_GiveCurEBuf(bcolors);
320 /*buf->r = palette[(i * 4) + 2];
321 buf->g = palette[(i * 4) + 1];
322 buf->b = palette[(i * 4)];
326 fpdata8(input, &buf->b);
327 fpdata8(input, &buf->g);
328 fpdata8(input, &buf->r);
329 fpdata8(input, &buf->a);
331 #if USE_ZLIB 1
332 buf->b = gzgetc(input);
333 buf->g = gzgetc(input);
334 buf->r = gzgetc(input);
336 /* I leave this just in case */
337 /* buf->a = fgetc(input); */
339 /* skip the alpha color */
340 gzgetc(input);
341 #else /* NOT USE_ZLIB */
342 buf->b = fgetc(input);
343 buf->g = fgetc(input);
344 buf->r = fgetc(input);
346 /* I leave this just in case */
347 /* buf->a = fgetc(input); */
349 /* skip the alpha color */
350 fgetc(input);
351 #endif /* NOT USE_ZLIB */
352 i++;
356 /* input the bits per pixel of the image
357 * input a 1 byte of data to process
359 static void
360 process_bitmap(BITMAP_HDATA *bmap, v_object *image, u8 *palette, u8 *data, EBUF *bcolors, u32 *x, u32 *y, int *aux, char **buf)
363 /* we will call functions depending on the bpp of the image */
364 switch (bmap->infoheader.bits)
366 case 1:
368 /* will do a loop to get each 8 pixels from the data */
370 /* this is pretty much for little endian
371 * the minimum data size we can have for a certain width is
372 * 32 bits (4 bytes increments). Those 32 bits will be able
373 * to hold up to 32 pixels. In case the width is higher than
374 * 32 pixels, it will put 32 bits until the whole width
375 * can be fulfilled.
377 /* we will need to have the width value because we will need
378 * to know how many bits we have to read from 32 bits (4 bytes).
380 /* aux will keep how many 32 bits still need to be done in a
381 * certain width
383 u8 temp;
384 /* double calc = 0; */
386 /* u8 r, g, b; */
388 const u8 values[8] = {
389 0x80,
390 0x40,
391 0x20,
392 0x10,
393 0x08,
394 0x04,
395 0x02,
396 0x01
398 u32 i = 0;
399 u32 max = 0;
401 if (*buf == NULL)
403 *buf = calloc(1, sizeof(char));
404 **buf = 0;
405 *aux = 0;
408 /* set up aux for remaining pixels */
409 if (*aux == 0)
410 *aux = bmap->infoheader.width;
412 /* set up the number of pixels we need to process in this cycle */
413 if (*aux > 8)
415 max = 8;
416 *aux = *aux - 8;
418 else
420 max = *aux;
421 *aux = 0;
424 temp = *data;
426 while (i < max)
428 BITMAP_COLOR *cbuf = NULL;
430 temp = *data & values[i];
433 if (temp)
434 temp = 1;
436 cbuf = Neuro_GiveEBuf(bcolors, temp);
438 if (IsLittleEndian())
439 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->r, cbuf->g, cbuf->b));
440 else
441 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->b, cbuf->g, cbuf->r));
443 *x = *x + 1;
444 i++;
447 if (*x > bmap->infoheader.width - 1)
449 *x = 0;
450 *y = *y + 1;
453 break;
455 case 4:
457 /* will do a loop to get each 2 pixels from the data */
458 u8 temp;
459 /* double calc = 0; */
461 /* u8 r, g, b; */
463 const u8 values[2] = {
464 0xF0,
465 0x0F,
467 u32 i = 0;
468 u32 max = 0;
470 if (*buf == NULL)
472 *buf = calloc(1, sizeof(char));
473 **buf = 0;
474 *aux = 0;
477 /* set up aux for remaining pixels */
478 if (*aux == 0)
479 *aux = bmap->infoheader.width;
481 /* set up the number of pixels we need to process in this cycle */
482 if (*aux > 2)
484 max = 2;
485 *aux = *aux - 2;
487 else
489 max = *aux;
490 *aux = 0;
493 temp = *data;
495 while (i < max)
497 BITMAP_COLOR *cbuf = NULL;
499 temp = *data & values[i];
500 if (IsLittleEndian())
502 if (temp > values[1])
503 temp >>= 4;
505 else
507 if (temp > values[1])
508 temp <<= 4;
511 cbuf = Neuro_GiveEBuf(bcolors, temp);
513 if (IsLittleEndian())
514 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->r, cbuf->g, cbuf->b));
515 else
516 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->b, cbuf->g, cbuf->r));
519 *x = *x + 1;
520 i++;
523 if (*x > bmap->infoheader.width - 1)
525 *x = 0;
526 *y = *y + 1;
530 break;
532 case 8:
534 /* will get the single pixel from the data */
535 u8 temp;
536 /* double calc = 0; */
538 /* u8 r, g, b; */
540 u32 i = 0;
541 u32 max = 0;
543 if (*buf == NULL)
545 *buf = calloc(1, sizeof(char));
546 **buf = 0;
547 *aux = 0;
550 /* set up aux for remaining pixels */
551 if (*aux == 0)
552 *aux = bmap->infoheader.width;
554 /* set up the number of pixels we need to process in this cycle */
555 if (*aux > 1)
557 max = 1;
558 *aux = *aux - 1;
560 else
562 max = *aux;
563 *aux = 0;
566 temp = *data;
568 while (i < max)
570 BITMAP_COLOR *cbuf = NULL;
571 temp = *data;
574 cbuf = Neuro_GiveEBuf(bcolors, temp);
576 if (IsLittleEndian())
577 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->r, cbuf->g, cbuf->b));
578 else
579 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB(cbuf->b, cbuf->g, cbuf->r));
581 *x = *x + 1;
582 i++;
585 if (*x > bmap->infoheader.width - 1)
587 *x = 0;
588 *y = *y + 1;
592 break;
594 case 16:
596 /* we do not support 16 bit because I think they
597 * use 24 bit for those. we'll see through use.
598 * if not, I really think this depth is pointless...
601 break;
603 case 24:
605 /* will need to gather the data for 2 other bytes to get a
606 * single pixel. We will use the auxiliary variable to keep
607 * track of where we are at in the gathering.
610 if (!*buf)
612 *buf = calloc(3, sizeof(u8));
613 *aux = 0;
616 (*buf)[*aux] = *data;
617 *aux = *aux + 1;
619 if (*aux >= 3)
621 *aux = 0;
623 if (bmap->infoheader.height == *y)
625 NEURO_ERROR("attempted to draw an invalid location", NULL);
626 return;
629 if (IsLittleEndian())
630 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB((*buf)[2], (*buf)[1], (*buf)[0]));
631 else
632 Neuro_PutPixel(image, *x, (bmap->infoheader.height - 1) - *y, Neuro_MapRGB((*buf)[0], (*buf)[1], (*buf)[2]));
634 *x = *x + 1;
637 if (*x > bmap->infoheader.width - 1)
639 *x = 0;
640 *y = *y + 1;
643 break;
645 case 32:
647 /* we do not support 32 bit because it is Very uncommon if it
648 * actually exist. Pretty much the same as 16 bpp.
651 break;
653 default:
655 /* an error occured */
657 break;
662 /* ctx being the bitmap loading context
663 * and loops being how many times the
664 * external function wants this function
665 * to load bytes from the image file.
667 static i8
668 processGradual_BMP(BMP_CTX *ctx, u32 loops)
670 if (ctx == NULL)
672 NEURO_WARN("argument ctx is NULL", NULL);
673 return -1;
676 if (ctx->f_bitmap == NULL)
678 NEURO_WARN("bitmap file descriptor is NULL", NULL);
679 return -1;
682 if (ctx->i == 0)
685 /* When the variable ctx->i equals 0, we
686 * initialise the buffers and prepare all the
687 * variables that will be used to load the
688 * image.
690 * this part of the code should only be ran
691 * once for each bitmaps.
694 ctx->bmap = parse_bitmap_header(ctx->f_bitmap);
696 /* we do consistency checks of the image to
697 * see if it is really a bitmap.
700 /* print_bitmap_infos(ctx->bmap); */
702 if (ctx->bmap->header.type != 0x4d42)
704 NEURO_WARN("Invalid bitmap file magic %d", ctx->bmap->header.type);
705 return -1;
709 /* if it is valid, we create the buffers */
710 Neuro_CreateEBuf(&ctx->bmap_colors);
711 Neuro_SetcallbEBuf(ctx->bmap_colors, &clean_bmap_color);
714 /* print_bitmap_infos(bmap); */
716 /* we set the variable psize to the size that
717 * the image data is minus the actual header size.
719 * it will be used to see when the function finished
720 * loading the data.
722 ctx->i = 0;
723 ctx->psize = ctx->bmap->header.size - (sizeof(BITMAP_HEADER) + sizeof(BITMAP_INFOHEADER));
724 ctx->psize = ctx->psize - (ctx->bmap->infoheader.ncolors * 4);
726 /* printf("data size %d\n", psize); */
728 /* we load the palette, if any */
729 if (ctx->bmap->infoheader.ncolors > 0)
731 process_palette(ctx->f_bitmap, ctx->bmap, ctx->bmap_colors);
734 /* we create the v_object which is the libneuro
735 * representation of the image.
739 /* Debug_Val(0, "image creation -- depth %d\n", ctx->bmap->infoheader.bits); */
740 /*ctx->output = Neuro_CreateVObject(0, ctx->bmap->infoheader.width, ctx->bmap->infoheader.height, ctx->bmap->infoheader.bits, rmask, gmask, bmask, amask);*/
741 ctx->output = Neuro_CreateVObject(0, ctx->bmap->infoheader.width, ctx->bmap->infoheader.height, ctx->bmap->infoheader.bits, 0, 0, 0, 0);
744 if (ctx->output == NULL)
746 NEURO_WARN("Created output v_object is NULL", NULL);
747 return -1;
751 /* semi static values to skip bytes that form 32 bit chunks in the data */
753 ctx->pixellen = (8 / (double)ctx->bmap->infoheader.bits);
754 ctx->msize = ctx->pixellen * 4;
756 /* we calculate the number of bytes there is per rows
757 * this is mainly so we can know how much "alignment"
758 * bytes there is (which need to be skipped)
761 ctx->wmult = (u32)ctx->bmap->infoheader.bits / 8;
763 if (ctx->wmult == 0)
764 ctx->wmult++;
766 ctx->wmult = ctx->wmult * ctx->bmap->infoheader.width;
769 ctx->increm = (u32)ctx->pixellen;
771 if (ctx->increm == 0)
772 ctx->increm++;
774 ctx->x = (u32)(ctx->bmap->infoheader.width / ctx->msize);
775 ctx->tmp = ctx->msize * ctx->x;
776 ctx->tmp = (double)ctx->bmap->infoheader.width - ctx->tmp;
777 ctx->tmp = ctx->tmp - 0.000001; /* to avoid bugs */
779 ctx->x = 0;
780 #if USE_ZLIB 1
781 gzseek(ctx->f_bitmap, ctx->bmap->header.offset, SEEK_SET);
782 #else /* NOT USE_ZLIB */
783 fseek(ctx->f_bitmap, ctx->bmap->header.offset, SEEK_SET);
784 #endif /* NOT USE_ZLIB */
786 NEURO_WARN("Bitmap size %d", ctx->psize);
787 Debug_Val(0, "Bitmap size %d\n", ctx->psize);
789 ctx->cut_size = ctx->psize / 30;
791 loops = ctx->cut_size;
793 /* we lock the surface */
794 Lib_LockVObject(ctx->output);
798 /* this part of the function takes
799 * care of the actual loading of the
800 * bitmap file. */
802 i32 initial = ctx->i;
804 /* while (ctx->i < ctx->psize) */
805 while (ctx->i < (initial + loops))
807 if (ctx->i > ctx->psize)
808 break;
810 if (ctx->tmp > 0)
812 /* skip bytes that are inside the bitmap for
813 * filling purpose. (the data is purposely filled
814 * with 0 bits so the data is 32bits aligned)
816 if (ctx->skip_i >= ctx->wmult)
818 ctx->calc = ctx->tmp / ctx->pixellen;
819 ctx->skip_i = (u32)ctx->calc;
820 if (ctx->skip_i < ctx->calc)
822 ctx->skip_i++;
824 ctx->skip_i = (4 - ctx->skip_i);
825 ctx->i += ctx->skip_i;
827 #if USE_ZLIB 1
828 gzseek(ctx->f_bitmap, ctx->bmap->header.offset + ctx->i, SEEK_SET);
829 #else /* NOT USE_ZLIB */
830 fseek(ctx->f_bitmap, ctx->bmap->header.offset + ctx->i, SEEK_SET);
831 #endif /* NOT USE_ZLIB */
834 printf("skipping %d bytes wmult %d width %d tmp %f plen %f calc %f\n",
835 skip_i,
836 wmult,
837 bmap->infoheader.width,
838 tmp,
839 pixellen, calc);
842 ctx->skip_i = 0;
845 ctx->skip_i += ctx->increm;
847 if (ctx->i >= ctx->psize)
848 break;
851 /* we fetch 8 bits from the file stream */
852 fpdata8(ctx->f_bitmap, &ctx->DATA);
854 /* we push the 8 bits along with various other
855 * variables to the bits processor.
858 process_bitmap(ctx->bmap, ctx->output, ctx->palette, &ctx->DATA,
859 ctx->bmap_colors, &ctx->x, &ctx->y, &ctx->aux_var, &ctx->aux_buf);
862 ctx->i++;
865 if (ctx->i >= ctx->psize)
866 { /* this bitmap finished being loaded, we free everything */
868 /* to prevent further calls to be processed */
869 ctx->i = -1;
871 if (ctx->bmap)
872 free(ctx->bmap);
873 if (ctx->buf)
874 free(ctx->buf);
875 if (ctx->aux_buf)
876 free(ctx->aux_buf);
878 Neuro_CleanEBuf(&ctx->bmap_colors);
880 #if USE_ZLIB 1
881 if (ctx->f_bitmap)
882 gzclose(ctx->f_bitmap);
883 #else /* NOT USE_ZLIB */
884 if (ctx->f_bitmap)
885 fclose(ctx->f_bitmap);
886 #endif /* NOT USE_ZLIB */
888 /* we return 100% done */
889 return 100;
892 /*Debug_Val(0, "((%d * 100) / %d) == %d\n",
893 ctx->i, ctx->psize,
894 (i8)((u32)((ctx->i * 100) / ctx->psize)));*/
896 /* we return the percentage of the file that
897 * is currently loaded.
899 return (i8)((u32)(ctx->i * 100) / ctx->psize);
902 /* this never happens unless the image was already loaded */
903 NEURO_WARN("Useless call of the function #%d", ctx->i);
904 return -1;
907 /*-------------------- Global Functions ----------------------------*/
909 v_object *
910 readBitmapFile(const char *bitmap)
912 BMP_CTX *ctx = NULL;
913 int _err = 0;
915 ctx = Bitmap_CreateCTX(bitmap);
917 if (ctx == NULL)
919 NEURO_WARN("Context creation failed", NULL);
920 return NULL;
923 while (1 != 2)
925 _err = Bitmap_Poll(ctx);
927 if (_err == 100)
928 break;
930 if (_err < 0)
932 NEURO_WARN("Poll failed...", NULL);
933 return NULL;
936 /* printf("loading progress : %d\n", _err); */
939 return Bitmap_DestroyCTX(ctx);
942 /*-------------------- Poll ----------------------------------------*/
944 /* returns a percentage of progress */
946 Bitmap_Poll(BMP_CTX *ctx)
948 return processGradual_BMP(ctx, ctx->cut_size);
951 /*-------------------- Constructor Destructor ----------------------*/
953 BMP_CTX *
954 Bitmap_CreateCTX(const char *path)
956 BMP_CTX *output;
958 output = calloc(1, sizeof(BMP_CTX));
960 if (output == NULL)
961 return NULL;
962 #if USE_ZLIB 1
963 output->f_bitmap = gzopen(path, "r"); /* can also be used for non compressed files */
964 #else /* NOT USE_ZLIB */
965 output->f_bitmap = fopen(path, "r");
966 #endif /* NOT USE_ZLIB */
968 if (output->f_bitmap == NULL)
970 free(output);
971 return NULL;
974 return output;
977 v_object *
978 Bitmap_DestroyCTX(BMP_CTX *ctx)
980 v_object *output = NULL;
982 if (ctx == NULL)
983 return NULL;
985 /* loading the image is done so we unlock */
986 Lib_UnlockVObject(ctx->output);
988 output = ctx->output;
990 free(ctx);
992 return output;