/* * lecture des fichiers BMP * ------------------------ * * ou "comment ne jamais se debarrasser de Kro$oft" * * Mais bon, le Paintbrush des petits m'incite a perseverer * sur la route du e-empire. Du moins tant que je n'ai pas * fait un clone de Paintbrush pour X11. Mais ceci est un * autre fantasme... * * 2 Octobre 2001: le boutisme va être bouté hors de ce module. */ #include #include #include "tthimage.h" #include "bmp.h" /* maybe I can hardcoded bmp.h here ? */ /*::------------------------------------------------------------------::*/ static void fatal_error(char *txt) { fprintf(stderr, "BMP: Fatal error: %s\n", txt); exit(10); } /*::------------------------------------------------------------------::*/ int Image_BMP_infos(char *nom, int *pw, int *ph, int *pt, int verb) { FILE *fp; BMPHEAD head; int foo; if (verb) printf("BMP_Infos : '%s'\n", nom); if ((fp=fopen(nom, "r")) == NULL) { fprintf(stderr, "BMP_Infos: can't open %s\n", nom); return FILE_NOT_FOUND; } foo = fread(&head, 1, sizeof(head), fp); fclose(fp); if (verb) { printf("signature %c%c filesize %8ld\n", head.id[0], head.id[1], head.filesize); printf("headerSize %8ld infoSize %8ld\n", head.headerSize, head.infoSize); printf("dimensions %ld x %ld x %d\n", head.width, head.height, head.bits); printf("colors: used %ld important %ld\n", head.clrused, head.clrimportant); printf("taille structure header %d\n", sizeof(BMPHEAD)); } /* * now, return some usefull informations. */ *pw = head.width; *ph = head.height; *pt = head.bits; return 0; } /*::------------------------------------------------------------------::*/ /* * Allocate memory and read a BMP file. */ #define PIX2BYTE(n) ((n+7)/8) Image_Desc * Image_BMP_alloc_load(char *nom, int reserved) { FILE *fp; BMPHEAD head; int ligne, foo, larg, col, ligne2; Image_Desc *image; uint8_t *buffer; if ((fp=fopen(nom, "r")) == NULL) { fprintf(stderr, "can't open %s\n", nom); return NULL; } foo = fread(&head, 1, sizeof(head), fp); #if DEBUG_LEVEL fprintf(stderr, "BMP: on a lu %d octets pour le header.\n", foo); #endif if ( head.id[0] != 'B' || head.id[1] != 'M' ) { fprintf(stderr, "BMP_Alloc_Load: BAD MAGIC %s\n", nom); return NULL; } #if DEBUG_LEVEL fprintf(stderr, "BMP_Alloc_Load: image depth = %d\n", head.bits); #endif /* * first step: allocating the memory. */ switch (head.bits) { case 1: case 4: case 8: fprintf(stderr, "bit depth %d not supported\n", head.bits); return NULL; break; case 24: if ( (image=Image_alloc(head.width, head.height, 3))==NULL) fatal_error("no memory for picture in 'alloc_load'\n"); if ( (buffer=(uint8_t *)malloc(4*head.width))==NULL) fatal_error("no memory for buffer in 'alloc_load'\n"); larg = head.width * 3; break; default: fprintf(stderr, "BMP Load: bit depth %d is unreal\n", head.bits); return NULL; break; } /* * round up to an even dword boundary (?) */ if (larg & 0x00000003) { larg |= 0x00000003; larg++; } /* * second step: load all the pixels. * * (no default case, filtered in first step) */ switch (head.bits) { case 24: for (ligne=0; ligneBpix[ligne2])[col] = buffer[ col*3 ]; (image->Gpix[ligne2])[col] = buffer[ (col*3) + 1 ]; (image->Rpix[ligne2])[col] = buffer[ (col*3) + 2 ]; } } break; } return image; } /*::------------------------------------------------------------------::*/ /* * Write a 24 bits bmp file. * * et cette fois-ci, on va faire gaffe au boutisme :) */ int Image_BMP_save_24(char *filename, Image_Desc *img, int flag) { FILE *fp; long grand; short court; int line, foo, bytes; uint8_t *Rptr, *Gptr, *Bptr; uint8_t *buffer, *ptr; #if DEBUG_LEVEL fprintf(stderr, "%s : writing %p to %s, flag=%d\n", __func__, img, filename, flag); #endif if ((fp=fopen(filename, "w")) == NULL) { fprintf(stderr, "can't open %s for writing\n", filename); return FILE_CREATE_ERR; } /* * round up to an even dword boundary (?) */ bytes = img->width; fprintf(stderr, "largeur 0 = %d (%d)\n", bytes, bytes & 3); /* OLD CODE - DOES NOT WORK AS EXPECTED - FIXME ONE DAY... if (bytes & 0x3) { bytes |= 0x3; bytes++; } */ switch (bytes & 0x3) { case 0: /* OK */ break; case 1: bytes+=3; break; case 2: bytes+=2; break; case 3: bytes+=1; break; } fprintf(stderr, "largeur 1 = %d\n", bytes); /* * writing the header */ fwrite("BM", 1, 2, fp); /* signature */ /* grand = 54L + (long)bytes*(long)img->height; */ /* file size */ grand = 54L + (long)img->width*(long)img->height; /* file size */ Image_basicIO_write_I_long(fp, grand); grand = 0; fwrite(&grand, 1, 2, fp); /* reserved by micro$oft ? */ fwrite(&grand, 1, 2, fp); /* reserved by micro$oft ? */ grand = 54L; /* ????? */ Image_basicIO_write_I_long(fp, grand); grand = 0x28L; /* always this value, but why ? */ Image_basicIO_write_I_long(fp, grand); grand = img->width; Image_basicIO_write_I_long(fp, grand); grand = img->height; Image_basicIO_write_I_long(fp, grand); court = 1; Image_basicIO_write_I_short(fp, court); /* biPlanes */ court = 24; Image_basicIO_write_I_short(fp, court); /* bits */ grand = 0L; Image_basicIO_write_I_long(fp, grand); /* biCompression */ grand = img->width * img->height * 3; /* biSizeImage */ /* grand = bytes * img->height * 3; */ /* biSizeImage */ Image_basicIO_write_I_long(fp, grand); grand = 1000; /* pixels per meter */ Image_basicIO_write_I_long(fp, grand); Image_basicIO_write_I_long(fp, grand); grand = 0; Image_basicIO_write_I_long(fp, grand); /* color-used */ Image_basicIO_write_I_long(fp, grand); /* color-important */ fflush(fp); /* * now, we can go, and write pixels datas... */ if ((buffer=(uint8_t *)malloc(sizeof(uint8_t)*4*img->width)) == NULL) fatal_error("no memory buffer for BMP24 save operation"); for (line=img->height-1; line>=0; line--) { ptr = buffer; Rptr = img->Rpix[line]; Gptr = img->Gpix[line]; Bptr = img->Bpix[line]; for (foo=0; foowidth; foo++) { *ptr++ = Bptr[foo]; *ptr++ = Gptr[foo]; *ptr++ = Rptr[foo]; } fwrite(buffer, 3, bytes, fp); } free(buffer); fclose(fp); return FUNC_IS_ALPHA; } /*::------------------------------------------------------------------::*/ /*::------------------------------------------------------------------::*/