#include"image.h" #include #include int Image::IsPng(Stuff::FileStream *stream) { int i; BYTE hdr[8],chdr[8]; bool ret; chdr[0]=0x89; chdr[1]=0x50; chdr[2]=0x4E; chdr[3]=0x47; chdr[4]=0x0D; chdr[5]=0x0A; chdr[6]=0x1A; chdr[7]=0x0A; stream->ReadBytes(hdr,8); ret=true; for(i=0;i<8;i++) { if(hdr[i]!=chdr[i]) ret=false; } stream->Rewind(); return ret; } FILE *imgpngfl=NULL; Stuff::FileStream *imgpngstream=NULL; void imlibPngReadCallback(png_structp png, png_bytep pbtData, png_size_t nLength) { Verify((imgpngstream!=NULL && imgpngfl==NULL) || (imgpngstream==NULL && imgpngfl!=NULL)); if(imgpngfl) fread((LPVOID)pbtData,nLength,1,imgpngfl); else imgpngstream->ReadBytes(pbtData,nLength); } void imlibPngWriteCallback(png_structp png, png_bytep pbtData, png_size_t nLength) { Verify((imgpngstream!=NULL && imgpngfl==NULL) || (imgpngstream==NULL && imgpngfl!=NULL)); if(imgpngfl) fwrite(pbtData,nLength,1,imgpngfl); else imgpngstream->WriteBytes(pbtData,nLength); } void Image::InternalLoadPng() { png_structp m_png; // Our PNG ADT png_infop m_pPngInfo; // Info retrieved from the PNG data up to IDAT chunk int m_nColorType; int m_nInterlaceType; int m_nBitDepth; // // Reading PNG files // m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); m_pPngInfo = png_create_info_struct(m_png); if( m_pPngInfo == NULL ) STOP(( "Error Reading file '%s'",fname )); #pragma warning( disable: 4611 ) setjmp(m_png->jmpbuf); #pragma warning( default: 4611 ) png_set_read_fn( m_png, 0, imlibPngReadCallback ); png_read_info(m_png, m_pPngInfo); png_uint_32 nDummy; int nCompressionType, nFilterType; png_get_IHDR(m_png, m_pPngInfo, &nDummy, &nDummy, &m_nBitDepth, &m_nColorType, &m_nInterlaceType, &nCompressionType, &nFilterType); /* if (m_nColorType == PNG_COLOR_TYPE_PALETTE) png_set_expand(m_png); if (m_nColorType == PNG_COLOR_TYPE_GRAY && m_nBitDepth < 8) png_set_expand(m_png); if (m_nColorType == PNG_COLOR_TYPE_GRAY) png_set_gray_to_rgb(m_png); if (png_get_valid(m_png, m_pPngInfo, PNG_INFO_tRNS)) png_set_expand(m_png); png_set_bgr(m_png); png_set_filler(m_png, 0xff, PNG_FILLER_AFTER); */ xpos=ypos=0; vxlen=xlen=m_pPngInfo->width; vylen=ylen=m_pPngInfo->height; Bpp=m_pPngInfo->pixel_depth; itype=ITYPE_RGB; if (m_nColorType == PNG_COLOR_TYPE_PALETTE) itype=ITYPE_INDEXED; if (m_nColorType == PNG_COLOR_TYPE_GRAY && m_nBitDepth < 8) itype=ITYPE_INDEXED; if (m_nColorType == PNG_COLOR_TYPE_GRAY) itype=ITYPE_INDEXED; if(itype==ITYPE_INDEXED) MakeGrayscalePalette(); IAlloc(); BYTE *dat=(BYTE *)Lock(); for( int y=0; yjmpbuf); #pragma warning( default: 4611 ) png_set_write_fn( m_png, 0, imlibPngWriteCallback ,NULL); if(itype!=ITYPE_INDEXED) { if(Bpp==24) MaskTo(RGBMask(0x0000ff,0x00ff00,0xff0000)); else if(Bpp==32) MaskTo(RGBMask(0x000000ff,0x0000ff00,0x00ff0000,0xff000000)); } if(itype==ITYPE_RGB) { if(GetBpp()==32) png_set_IHDR(m_png, m_pPngInfo, xlen, ylen, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); else png_set_IHDR(m_png, m_pPngInfo, xlen, ylen, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); } else { png_set_IHDR(m_png, m_pPngInfo, xlen, ylen, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); } png_write_info(m_png, m_pPngInfo); BYTE *dat=(BYTE *)Lock(); for( int y=0; yReadBytes(hdr,8); for(i=0;i<8;i++) { if(hdr[i]!=chdr[i]) GENFERR("Not a png file"); } stream->ReadBytes(&chunksize,4); stream->ReadBytes(&chunktag,4); stream->ReadBytes(&xlen,4); stream->ReadBytes(&ylen,4); stream->ReadBytes(&ylen,4); Bpp=0; stream->ReadBytes(&Bpp,1); BYTE tbt; stream->ReadBytes(&tbt,1); if(tbt==3) itype=ITYPE_INDEXED; else itype=ITYPE_RGB; if(itype!=ITYPE_INDEXED) { if(Bpp==24) Mask.Set(0x0000ff,0x00ff00,0xff0000); else if(Bpp==32) Mask.Set(0x0000ff00,0x00ff0000,0xff000000,0x000000ff); } } int Image::IsPng() { char *spos; spos=NULL; int i,slen=strlen(fname); for(i=slen-1;i>=0 && fname[i]!='.';i--); if(i<0) return 0; if(fname[i]=='.') spos=fname+i+1; return !strcmpi("png",spos); } int Image::IsPng(FILE *fl) { if(!fl) GENNFERR("Invalid File"); int i; BYTE hdr[8],chdr[8]; int fpos=ftell(fl); bool ret; chdr[0]=0x89; chdr[1]=0x50; chdr[2]=0x4E; chdr[3]=0x47; chdr[4]=0x0D; chdr[5]=0x0A; chdr[6]=0x1A; chdr[7]=0x0A; fread(hdr,8,1,fl); ret=true; for(i=0;i<8;i++) { if(hdr[i]!=chdr[i]) ret=false; } fseek(fl,fpos,SEEK_SET); return ret; } void Image::LoadPng(char *str) { Stuff::FileStream stream; stream.Open(str,Stuff::FileStream::ReadOnly); LoadPng(&stream); strcpy(fname,str); } void Image::GetPngInfo(FILE *fl) { int i,pos; BYTE hdr[8],chdr[8]; pos=ftell(fl); unsigned int cnkhdr=0,chunksize,chunktag; chdr[0]=0x89; chdr[1]=0x50; chdr[2]=0x4E; chdr[3]=0x47; chdr[4]=0x0D; chdr[5]=0x0A; chdr[6]=0x1A; chdr[7]=0x0A; fread(hdr,8,1,fl); for(i=0;i<8;i++) { if(hdr[i]!=chdr[i]) GENFERR("Not a png file"); } fread(&chunksize,4,0,fl); fread(&chunktag,4,0,fl); fread(&xlen,4,0,fl); fread(&ylen,4,0,fl); fread(&ylen,4,0,fl); Bpp=(int)getc(fl); if(getc(fl)==3) itype=ITYPE_INDEXED; else itype=ITYPE_RGB; if(itype!=ITYPE_INDEXED) { if(Bpp==24) Mask.Set(0x0000ff,0x00ff00,0xff0000); else if(Bpp==32) Mask.Set(0x0000ff00,0x00ff0000,0xff000000,0x000000ff); } } void Image::GetPngInfo(char *str) { Stuff::FileStream stream; stream.Open(str,Stuff::FileStream::ReadOnly); GetPngInfo(&stream); strcpy(fname,str); } void Image::SavePng(char *str) { Stuff::FileStream stream; stream.Open(str,Stuff::FileStream::WriteOnly); SavePng(&stream); strcpy(fname,str); }