// Yes, you can use LoadImage too, but that creates a device // dependent bitmap and you want to stay the fsck away from those. bool CBmpFile::Load(const char *fpath) { FILE *fp= fopen(fpath, "rb"); CLDIB *dib= NULL; try { if(!fp) throw CImgFile::sMsgs[ERR_NO_FILE]; BITMAPFILEHEADER bmfh; fread(&bmfh, sizeof(BITMAPFILEHEADER), 1,fp); // Whoa, not a bitmap, back off if(bmfh.bfType != BMP_TYPE) // 4D42h = "BM". throw CImgFile::sMsgs[ERR_FORMAT]; BITMAPINFOHEADER bmih; bool bCore; // check for bm version first :( fread(&bmih, 4, 1, fp); if(bmih.biSize == sizeof(BITMAPCOREHEADER)) // crap! v2.x BMP { bCore= true; bmih.biSize= BMIH_SIZE; WORD wd; fread(&wd, 2,1,fp); bmih.biWidth= wd; fread(&wd, 2,1,fp); bmih.biHeight= wd; fread(&bmih.biPlanes, 2,1,fp); fread(&bmih.biBitCount, 2,1,fp); memset(&bmih.biCompression, 0, BMIH_SIZE-sizeof(BITMAPCOREHEADER)); } else // normal v3.0 BMP fread(&bmih.biWidth, BMIH_SIZE-4, 1, fp); if(bmih.biPlanes > 1) // no color planes, plz throw sMsgs[ERR_BMP_PLANES]; if(bmih.biCompression != BI_RGB) // no compression either throw sMsgs[ERR_BMP_CPRS]; int dibP, dibHa, dibS; dibHa= abs(bmih.biHeight); dibP= dib_align(bmih.biWidth, bmih.biBitCount); dibS= dibP*dibHa; // set manually, just to be sure bmih.biSizeImage= dibS; // ditto for ClrUsed if(bmih.biBitCount <=8 && bmih.biClrUsed == 0) bmih.biClrUsed= 1<<bmih.biBitCount; // now we set-up the full bitmap dib= dib_alloc(bmih.biWidth, dibHa, bmih.biBitCount, NULL, true); if(dib == NULL) throw CImgFile::sMsgs[ERR_ALLOC]; // read the palette fread(dib_get_pal(dib), RGB_SIZE, bmih.biClrUsed, fp); // read image fread(dib_get_img(dib), dibS, 1, fp); if(bmih.biHeight>=0) // -> TD image dib_vflip(dib); } // </try> catch(const char *msg) { SetMsg(msg); dib_free(dib); dib= NULL; } if(fp) fclose(fp); if(!dib) return false; // if we're here we've succeeded SetMsg(CImgFile::sMsgs[ERR_NONE]); dib_free(Attach(dib)); SetBpp(dib_get_bpp(dib)); SetPath(fpath); return true; }
void cSubtitleRegion::SetDepth(int Depth) { if (Depth > 0 && Depth < 4) SetBpp(1 << Depth); }
// xxx_load(const char *fname, PDIBDATA *ppdib, IMG_FMT_INFO *pifi) bool CTgaFile::Load(const char *fpath) { FILE *fp= fopen(fpath, "rb"); CLDIB *dib= NULL; TGAHDR hdr; try { if(!fp) throw CImgFile::sMsgs[ERR_NO_FILE]; fread(&hdr, sizeof(TGAHDR), 1, fp); // ignore image desc (if any) fseek(fp, hdr.id_len, SEEK_CUR); int imgW, imgH, imgB, imgP; imgW= hdr.width; imgH= hdr.height; imgB= hdr.img_bpp; imgP= dib_align(imgW, imgB); // Set-up the full bitmap dib= dib_alloc(imgW, imgH, imgB, NULL, true); if(dib == NULL) throw CImgFile::sMsgs[ERR_ALLOC]; // === get color map === if(hdr.has_table) { if(!tga_read_pal(dib, &hdr, fp)) throw sMsgs[ERR_TGA_BADPAL]; } int ii; int tgaP= (imgW*imgB+7)/8; BYTE *imgD= dib_get_img(dib); switch(hdr.type) { case TGA_BW: case TGA_PAL: case TGA_true: for(ii=0; ii<imgH; ii++) fread(&imgD[ii*imgP], 1, tgaP, fp); break; case TGA_BW_RLE: case TGA_PAL_RLE: case TGA_true_RLE: tga_unrle(dib, &hdr, fp); break; default: throw sMsgs[ERR_TGA_VERSION]; } // TGA's are bottom-up by default, flip if necessary if(~hdr.img_desc & TGA_VFLIP) dib_vflip(dib); } // </try> catch(const char *msg) { SetMsg(msg); dib_free(dib); dib= NULL; } // cleanup if(!dib) return false; // if we're here we've succeeded SetMsg(CImgFile::sMsgs[ERR_NONE]); dib_free(Attach(dib)); SetBpp(dib_get_bpp(dib)); SetPath(fpath); return true; }