BMMRES BitmapIO_YUV::Write(int frame) { //-- If we haven't gone through an OpenOutput(), leave if (openMode != BMM_OPEN_W) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); }
BMMRES BitmapIO_BMP::OpenOutput(BitmapInfo *fbi, Bitmap *map) { if (openMode != BMM_NOT_OPEN) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); if (!map) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); //-- Save Image Info Data if (!mParams.saved) ReadCfg(); bi.CopyImageInfo(fbi); bi.SetUpdateWindow(fbi->GetUpdateWindow()); this->map = map; openMode = BMM_OPEN_W; return (BMMRES_SUCCESS); }
BMMRES BitmapIO_GIF::Write(int frame) { //-- If we haven't gone through an OpenOutput(), leave if (openMode != BMM_OPEN_W) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); //-- Resolve Filename -------------------------------- TCHAR filename[MAX_PATH]; if (frame == BMM_SINGLEFRAME) { _tcscpy(filename,bi.Name()); } else { if (!BMMCreateNumberedFilename(bi.Name(),frame,filename)) { return (ProcessImageIOError(&bi,BMMRES_NUMBEREDFILENAMEERROR)); } } //-- Create Image File ------------------------------- File file(filename, _T("wb")); if (!file.stream) { return (ProcessImageIOError(&bi)); } // Below this line formatted for Tom's editor (sorry.) outStream = file.stream; // Find out what kind of output file we're dealing with saveStorage = map->Storage(); if(!saveStorage) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); int result = SaveGIF(map); switch(result) { case 1: return BMMRES_SUCCESS; case 0: default: return (ProcessImageIOError(&bi,GetString(IDS_WRITE_ERROR))); } }
BitmapStorage *BitmapIO_GIF::Load(BitmapInfo *fbi, Bitmap *map, BMMRES *status) { //-- Initialize Status Optimistically *status = BMMRES_SUCCESS; //-- Make sure nothing weird is going on if(openMode != BMM_NOT_OPEN) { *status = ProcessImageIOError(fbi,BMMRES_INTERNALERROR); return NULL; } openMode = BMM_OPEN_R; loadMap = map; BitmapStorage *s = ReadGIFFile(fbi, map->Manager(), status); if(!s) return NULL; //-- Set the storage's BitmapInfo s->bi.CopyImageInfo(fbi); return s; }
BMMRES BitmapIO_CIN::GetImageInfoDlg(HWND hWnd, BitmapInfo* bmi, const TCHAR* fname) { BitmapInfo bInfo; if (!bmi) { assert(FALSE); return ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Internal_Error)); } bInfo.Copy(bmi); if (fname) bInfo.SetName(fname); BMMRES bmmResult = GetImageInfo(&bInfo); if (bmmResult != BMMRES_SUCCESS) { return bmmResult; } #ifdef BASIC_INFO_DLG DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CIN_BASIC_INFO), hWnd, (DLGPROC) CIN_ImageInfoDialogProc, (LPARAM) this); #else DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CIN_INFO), hWnd, (DLGPROC) CIN_ImageInfoDialogProc, (LPARAM) this); #endif return BMMRES_SUCCESS; }
BMMRES BitmapIO_CIN::OpenOutput(BitmapInfo* bmi, Bitmap* bm) { if (openMode != BMM_NOT_OPEN) return ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Internal_Error)); if (!bm) return ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Internal_Error)); map = bm; bi.CopyImageInfo(bmi); bi.SetUpdateWindow(bmi->GetUpdateWindow()); openMode = BMM_OPEN_W; return BMMRES_SUCCESS; }
BMMRES BitmapIO_GIF::OpenOutput(BitmapInfo *fbi, Bitmap *map) { if (openMode != BMM_NOT_OPEN) return (ProcessImageIOError(fbi,BMMRES_INTERNALERROR)); if (!map) return (ProcessImageIOError(fbi,BMMRES_INTERNALERROR)); //-- Save Image Info Data bi.CopyImageInfo(fbi); this->map = map; openMode = BMM_OPEN_W; return BMMRES_SUCCESS; }
BMMRES BitmapIO_EPS::OpenOutput(BitmapInfo *fbi, Bitmap *map) { if (openMode != BMM_NOT_OPEN) return (ProcessImageIOError(fbi,BMMRES_INTERNALERROR)); if (!map) return (ProcessImageIOError(fbi,BMMRES_INTERNALERROR)); // Save Image Info Data bi.CopyImageInfo (fbi); // Above doesn't copy window so do that here hWnd = fbi->GetUpdateWindow(); this->map = map; openMode = BMM_OPEN_W; return BMMRES_SUCCESS; }
BMMRES BitmapIO_PNG::Write(int frame) { //-- If we haven't gone through an OpenOutput(), leave if (openMode != BMM_OPEN_W) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); //-- Resolve Filename -------------------------------- TCHAR filename[MAX_PATH]; if (frame == BMM_SINGLEFRAME) { _tcscpy(filename,bi.Name()); } else { if (!BMMCreateNumberedFilename(bi.Name(),frame,filename)) { return (ProcessImageIOError(&bi,BMMRES_NUMBEREDFILENAMEERROR)); } } return Save(filename, map); }
BMMRES BitmapIO_PNG::OpenOutput(BitmapInfo *fbi, Bitmap *map) { if(openMode != BMM_NOT_OPEN) return (ProcessImageIOError(fbi, BMMRES_INTERNALERROR)); if(!map) return (ProcessImageIOError(fbi,BMMRES_INTERNALERROR)); //-- Check for Default Configuration ----------------- if (!cfg.saved) ReadCfg(); //-- Save Image Info Data bi.CopyImageInfo(fbi); bi.SetUpdateWindow(fbi->GetUpdateWindow()); this->map = map; openMode = BMM_OPEN_W; return BMMRES_SUCCESS; }
BMMRES BitmapIO_CIN::GetImageInfo(BitmapInfo* bmi) { if (!bmi) { assert(FALSE); return ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Internal_Error)); } if (mStream) fclose(mStream); File file(bmi->Name(), _T("rb")); if (!file.mStream) return ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_File_Open_Error)); mStream = file.mStream; if (openMode != BMM_NOT_OPEN) return ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Internal_Error)); if (mCineonImage.ReadHeader(mStream) == FALSE) return ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Corrupt_File_Error)); if (mCineonImage.VerifyHeader() == FALSE) return ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Invalid_Header_Error)); // FIXME read the header bmi->SetWidth(mCineonImage.GetPixelsPerLine()); bmi->SetHeight(mCineonImage.GetLinesPerImage()); bmi->SetType(BMM_TRUE_48); bmi->SetAspect(1.0f); bmi->SetGamma(mCineonImage.GetImageGamma()); bmi->SetFirstFrame(0); bmi->SetLastFrame(0); return BMMRES_SUCCESS; }
BMMRES BitmapIO_GIF::GetImageInfo ( BitmapInfo *fbi ) { //-- Get File Header File file(fbi->Name(), _T("rb")); inStream = file.stream; if(inStream == NULL) return (ProcessImageIOError(fbi)); if(ReadHeader()) { fbi->SetWidth(image.w); fbi->SetHeight(image.h); // fbi->SetGamma (1.0f); fbi->SetAspect (1.0f); fbi->SetFirstFrame(0); fbi->SetLastFrame(0); fbi->SetType(storageType); return BMMRES_SUCCESS; } else return (ProcessImageIOError(fbi,BMMRES_BADFILEHEADER)); }
BMMRES BitmapIO_BMP::GetImageInfo ( BitmapInfo *fbi ) { //-- Open BMP File ----------------------------------- File file(fbi->Name(), _T("rb")); if (!file.stream) return (ProcessImageIOError(fbi)); //-- Read File Header -------------------------------- if (!ReadBimpHeader(file.stream)) return (ProcessImageIOError(fbi,BMMRES_BADFILEHEADER)); //-- Update Bitmap Info ------------------------------ fbi->SetWidth( (WORD)bmi.biWidth ); fbi->SetHeight((WORD)bmi.biHeight); switch (bmi.biBitCount) { case 1: fbi->SetType(BMM_LINE_ART); break; case 4: fbi->SetType(BMM_BMP_4); break; case 8: fbi->SetType(BMM_PALETTED); break; case 16: fbi->SetType(BMM_TRUE_16); break; case 24: fbi->SetType(BMM_TRUE_24); break; case 32: fbi->SetType(BMM_TRUE_32); break; default: fbi->SetType(BMM_NO_TYPE); break; } // fbi->SetGamma(1.0f); fbi->SetAspect(1.0f); fbi->SetFirstFrame(0); fbi->SetLastFrame(0); return BMMRES_SUCCESS; }
BMMRES BitmapIO_CIN::Write(int frameNum) { TCHAR filename[MAX_PATH]; if (openMode != BMM_OPEN_W) return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_Internal_Error)); if (frameNum != BMM_SINGLEFRAME) { if (!BMMCreateNumberedFilename(bi.Name(), frameNum, filename)) { return ProcessImageIOError(&bi, BMMRES_NUMBEREDFILENAMEERROR); } } else { _tcscpy(filename, bi.Name()); } File file(filename, _T("wb")); if (!file.mStream) return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_File_Open_Error)); mStream = file.mStream; BitmapStorage* bms = map->Storage(); if (!bms) return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_Internal_Error)); unsigned int height = map->Height(); unsigned int width = map->Width(); CineonFile cineonImage; cineonImage.SetImageFileName(filename); char cDate[128] = ""; char cTime[128] = ""; WIN32_FIND_DATA findFile; HANDLE findhnd = FindFirstFile(bi.Name(), &findFile); SYSTEMTIME time; SYSTEMTIME local; FindClose(findhnd); if (findhnd != INVALID_HANDLE_VALUE) { FileTimeToSystemTime(&findFile.ftLastWriteTime, &time); if (!SystemTimeToTzSpecificLocalTime(NULL, &time, &local)) local = time; sprintf(cDate,"%d:%02d:%02d", local.wYear, local.wMonth, local.wDay); sprintf(cTime,"%02d:%02d:%02d", local.wHour, local.wMinute, local.wSecond); } cineonImage.SetImageCreationDate(cDate); cineonImage.SetImageCreationTime(cTime); cineonImage.SetImageInputDevice("3D Studio MAX"); cineonImage.SetImageInputDeviceModelNumber("4.0"); char buf[CINEON_HDR_DEVICE_SERIAL_NUMBER_LENGTH]; sprintf(buf, "%d", HardwareLockID()); cineonImage.SetImageInputDeviceSerialNumber(buf); cineonImage.SetImageOrientation(0); cineonImage.SetNumberChannels(3); for (int i = 0; i < 3; i++) { cineonImage.SetBitsPerPixel(i, 10); cineonImage.SetPixelsPerLine(i, width); cineonImage.SetLinesPerImage(i, height); } // Put in the NTSC, defaults. max don't allow for correction/modification // FIXME cineonImage.SetWhitePt(0.3324f, 0.3474f); cineonImage.SetRedPt(0.67f, 0.33f); cineonImage.SetGreenPt(0.21f, 0.71f); cineonImage.SetBluePt(0.14f, 0.08f); cineonImage.SetDataInterleave(0); cineonImage.SetPacking(5); cineonImage.SetSigned(0); cineonImage.SetSense(0); cineonImage.SetEOLPadding(0); cineonImage.SetEOCPadding(0); cineonImage.SetImageGamma(1.0f); cineonImage.SetImageXOffset(0); cineonImage.SetImageYOffset(0); cineonImage.SetFramePosition(frameNum); if (cineonImage.VerifyHeader() == FALSE) return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_Invalid_Header_Error)); if (!cineonImage.IsSupported()) return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_Unsupported_File_Error)); BMM_Color_64* scanLine = (BMM_Color_64*) calloc(width, sizeof(BMM_Color_64)); if (!scanLine) return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_Memory_Error)); if (!cineonImage.SetLUTs(10, (float) mUserData.mRefWhite, (float) mUserData.mRefBlack)) return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_Memory_Error)); for (unsigned int lineCnt = 0; lineCnt < height; lineCnt++) { GetOutputPixels(0, lineCnt, width, scanLine); if (!cineonImage.WriteScanLine(file.mStream, (unsigned short*) scanLine, lineCnt, width)) { if (scanLine) { free(scanLine); scanLine = NULL; } return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_File_IO_Error)); } } if (scanLine) { free(scanLine); scanLine = NULL; } fpos_t fileSize; fgetpos(file.mStream, &fileSize); cineonImage.SetFileSize((unsigned int) fileSize); if (cineonImage.WriteHeader(mStream) == FALSE) return ProcessImageIOError(&bi, GetResIDCaption(IDS_CIN_File_IO_Error)); return BMMRES_SUCCESS; }
BitmapStorage *BitmapIO_BMP::Load(BitmapInfo *fbi, Bitmap *map, BMMRES *status) { RGBQUAD *rgb = NULL; BMM_Color_48 *pal = NULL; BitmapStorage *s = NULL; BMM_Color_64 *b = NULL; BYTE *p = NULL; BYTE *b8 = NULL; BYTE *b4 = NULL; INT_PTR pixels = 0; int rows = 0; int w = 0; int wb = 0; int h = 0; int j; //-- Initialize Status Optimistically *status = BMMRES_SUCCESS; //-- Make sure nothing weird is going on if(openMode != BMM_NOT_OPEN) { *status = ProcessImageIOError(fbi,BMMRES_INTERNALERROR); return NULL; } //-- Open BMP File ----------------------------------- File file(fbi->Name(), _T("rb")); if (!file.stream) { *status = ProcessImageIOError(fbi); return(NULL); } //-- Read File Header -------------------------------- if (!ReadBimpHeader(file.stream)) { *status = ProcessImageIOError(fbi,BMMRES_BADFILEHEADER); return (NULL); } //-- Update Bitmap Info ------------------------------ fbi->SetWidth( (WORD)bmi.biWidth ); fbi->SetHeight((WORD)bmi.biHeight); if ((bmi.biBitCount != 32 && bmi.biBitCount != 24 && bmi.biBitCount != 8 && bmi.biBitCount != 4) || bmi.biCompression != BI_RGB) { *status = ProcessImageIOError(fbi,GetString(IDS_UNSUPPORTED)); return(NULL); } // fbi->SetGamma(1.0f); fbi->SetAspect(1.0f); switch(bmi.biBitCount) { case 32: fbi->SetType(BMM_TRUE_32); // [Kai@8/19/2008] We need to set this flag so that the alpha storage will be created in BMMCreateStorage fbi->SetFlags(MAP_HAS_ALPHA); break; case 24: fbi->SetType(BMM_TRUE_24); break; case 8: case 4: //-- We don't have a 4 bit bitmap storage anyway. //-- So force 4 bit to 8 bit fbi->SetType(BMM_PALETTED); break; } fbi->SetFirstFrame(0); fbi->SetLastFrame(0); //-- Create Image Storage ---------------------------- switch(bmi.biBitCount) { case 32: s = BMMCreateStorage(map->Manager(), BMM_TRUE_32); break; case 24: s = BMMCreateStorage(map->Manager(),BMM_TRUE_32); break; case 8: case 4: //-- We don't have a 4 bit bitmap storage anyway. //-- So force 4 bit storage to 8 bit storage s = BMMCreateStorage(map->Manager(),BMM_PALETTED); break; } if(!s) { *status = ProcessImageIOError(fbi,BMMRES_CANTSTORAGE); return NULL; } //-- Allocate Image Storage -------------------------- if (s->Allocate(fbi,map->Manager(),BMM_OPEN_R)==0) { memory_error_out: *status = ProcessImageIOError(fbi,BMMRES_MEMORYERROR); goto bail_out; io_error_out: *status = ProcessImageIOError(fbi); bail_out: if (s) delete s; if (b) free(b); if (p) free(p); if (rgb) free(rgb); if (pal) free(pal); return NULL; } switch(bmi.biBitCount) { case 4: //-- Read 4 bit Palette ------------------------------------ if (!bmi.biClrUsed) bmi.biClrUsed = 16; rgb = (RGBQUAD *)malloc(bmi.biClrUsed * sizeof(RGBQUAD)); if (!rgb) goto memory_error_out; pal = (BMM_Color_48 *)malloc(bmi.biClrUsed * sizeof(BMM_Color_48)); if (!pal) goto memory_error_out; if (fread(rgb,sizeof(RGBQUAD),bmi.biClrUsed,file.stream) != bmi.biClrUsed) goto io_error_out; for (j = 0; j < (int)bmi.biClrUsed; j++) { pal[j].r = rgb[j].rgbRed << 8; pal[j].g = rgb[j].rgbGreen << 8; pal[j].b = rgb[j].rgbBlue << 8; } s->SetPalette(0,bmi.biClrUsed,pal); free(pal); free(rgb); pal = NULL; rgb = NULL; //-- Read Image (4 Bits) ----------------------------- w = fbi->Width(); wb = ( ((fbi->Width()+1)/2)+ 3) & ~3; // width must be multiple of 4 h = fbi->Height() - 1; p = (BYTE *)malloc(wb); b4 = (BYTE *)malloc(w); if (!p || !b4) goto memory_error_out; do { pixels = fread(p,1,wb,file.stream); if (pixels != wb && pixels != 0) goto io_error_out; if (pixels) { // -- the 4bit buffer p has two pixels per byte. // -- convert it to 8 bit buffer b8 that has one pixel per byte for(j=0;j<w;j++) { b4[j] = (j%2) ? (p[j/2] & 0x0f) : (p[j/2] >> 4); } s->PutIndexPixels(0,(h - rows),w,b4); rows++; if (rows>h) break; } //-- Progress Report if (fbi->GetUpdateWindow()) SendMessage(fbi->GetUpdateWindow(),BMM_PROGRESS,rows,h); } while (pixels); break; case 8: //-- Read 8 bitPalette ------------------------------------ if (!bmi.biClrUsed) bmi.biClrUsed = 256; rgb = (RGBQUAD *)malloc(bmi.biClrUsed * sizeof(RGBQUAD)); if (!rgb) goto memory_error_out; pal = (BMM_Color_48 *)malloc(bmi.biClrUsed * sizeof(BMM_Color_48)); if (!pal) goto memory_error_out; if (fread(rgb,sizeof(RGBQUAD),bmi.biClrUsed,file.stream) != bmi.biClrUsed) goto io_error_out; for ( j = 0; j < (int)bmi.biClrUsed; j++) { pal[j].r = rgb[j].rgbRed << 8; pal[j].g = rgb[j].rgbGreen << 8; pal[j].b = rgb[j].rgbBlue << 8; } s->SetPalette(0,bmi.biClrUsed,pal); free(pal); free(rgb); pal = NULL; rgb = NULL; //-- Read Image (8 Bits) ----------------------------- w = (fbi->Width() + 3) & ~3; // width must be multiple of 4 h = fbi->Height() - 1; p = (BYTE *)malloc(w); if (!p) goto memory_error_out; do { pixels = fread(p,1,w,file.stream); if (pixels != w && pixels != 0) goto io_error_out; if (pixels) { s->PutIndexPixels(0,(h - rows),fbi->Width(),p); rows++; if (rows>h) break; } //-- Progress Report if (fbi->GetUpdateWindow()) SendMessage(fbi->GetUpdateWindow(),BMM_PROGRESS,rows,h); } while (pixels); break; case 24: case 32: { //-- Read Image (24/32 Bits) ---------------------------- bool hasAlpha = (bmi.biBitCount == 32); w = fbi->Width(); if(!hasAlpha) { wb = (fbi->Width() * 3 + 3) & ~3; // width bytes must be multiple of 4 } else { wb = (fbi->Width() * 4); } h = fbi->Height() - 1; b = (BMM_Color_64 *)malloc(fbi->Width()*sizeof(BMM_Color_64)); p = (BYTE *)malloc(wb); if(!b || !p) goto memory_error_out; BYTE *ptr; do { pixels = fread(p,1,wb,file.stream); if (pixels != wb && pixels != 0) goto io_error_out; if (pixels) { ptr = p; for (int x = 0; x < w; x++) { b[x].b = (WORD)((*ptr++) << 8); b[x].g = (WORD)((*ptr++) << 8); b[x].r = (WORD)((*ptr++) << 8); if(hasAlpha) { b[x].a = (WORD)((*ptr++) << 8); } } if (s->PutPixels(0,(h - rows),w,b)!=1) goto io_error_out; rows++; if (rows>h) break; } //-- Progress Report if (fbi->GetUpdateWindow()) SendMessage(fbi->GetUpdateWindow(),BMM_PROGRESS,rows,h); } while (pixels); } break; } //-- Clean Up ---------------------------------------- if (b) free(b); if (p) free(p); if (b8)free(b8); if (b4)free(b4); //-- Set the storage's BitmapInfo s->bi.CopyImageInfo(fbi); return s; }
/* This function handles writing out EPS files. It is written to be * as "PostScript friendly as possible", i.e. it: * 1) Uses a fairly full set of DSC comments * 2) Uses its own dictionary instead of assuming there is room in * the current one * 3) If colorimage is not supported on the PostScript interpreter * and an RGB image was selected the image will be rendered as grayscale * instead using the NTSC conversion. */ BMMRES BitmapIO_EPS::Save(const TCHAR *name, Bitmap *bitmap) { int xOffset = 0; // Offset for the lower left corner int yOffset = 0; // of the image */ int status; if (! bitmap) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); /* Compute the position on the page to output the image */ Position (bitmap, &xOffset, &yOffset); // for a360 support - allows binary diff syncing MaxSDK::Util::Path storageNamePath(name); storageNamePath.SaveBaseFile(); if ((mOutStream = _tfopen(name, _T("wb"))) == NULL) return (ProcessImageIOError(&bi)); /* If a preview is desired then write the TIFF section */ if (userSettings.preview) { status = WritePreview (userSettings.colorType, userSettings.orientation, userSettings.xResolution, userSettings.yResolution, bitmap); if (status != BMMRES_SUCCESS) { fclose (mOutStream); return status; } } /* First the PostScript header */ status = WriteHeader (bitmap, xOffset, yOffset); if (status != BMMRES_SUCCESS) { fclose (mOutStream); return status; } /* Now the image data itself */ status = WriteImagePosition (bitmap, xOffset, yOffset); if (status != BMMRES_SUCCESS) { fclose (mOutStream); return status; } if (userSettings.binary && userSettings.colorType == RGBIMAGE) status = WriteBinaryRGBImage (bitmap); else if (userSettings.binary && userSettings.colorType == GRAYIMAGE) status = WriteBinaryGrayImage (bitmap); else if (userSettings.colorType == RGBIMAGE) status = WriteAsciiRGBImage (bitmap); else status = WriteAsciiGrayImage (bitmap); if (status != BMMRES_SUCCESS) { fclose (mOutStream); return status; } /* Now the trailer */ status = WriteTrailer (); /* If a preview was requested we need to now figure out the length of the * PostScript portion and write it to the header */ if (userSettings.preview) status = WritePSLength (userSettings.colorType, map); fclose (mOutStream); return (status); }
BMMRES BitmapIO_BMP::Write(int frame) { BMMRES result = BMMRES_SUCCESS; //-- If we haven't gone through an OpenOutput(), leave if (openMode != BMM_OPEN_W) return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); //-- Resolve Filename -------------------------------- TCHAR filename[MAX_PATH]; if (frame == BMM_SINGLEFRAME) { _tcscpy(filename,bi.Name()); } else { if (!BMMCreateNumberedFilename(bi.Name(),frame,filename)) return (ProcessImageIOError(&bi,BMMRES_NUMBEREDFILENAMEERROR)); } //-- Create Image File ------------------------------- File file(filename, _T("wb")); if (!file.stream) return (ProcessImageIOError(&bi)); //-- Create File Header------------------------------- BITMAPFILEHEADER hdr; PBITMAPINFO pbmi; int lx,y; memset(&hdr,0,sizeof(BITMAPFILEHEADER)); hdr.bfType = 0x4d42; hdr.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER); //-- Pallette buffer and pixel buffer for 8bit output PixelBuf8 *pixBuf; BYTE *pix; PixelBuf48 *palBuf; BMM_Color_48 *pal; int w = map->Width(); int wb = (map->Width() + 3) & ~3; // width must be multiple of 4 int h = map->Height(); switch(mParams.outDepth) { //-- Paletted BMP required case BMM_PALETTED: pixBuf = new PixelBuf8(wb*h); palBuf = new PixelBuf48(256); if( (!pixBuf) || (!palBuf) ) ProcessImageIOError(&bi,BMMRES_MEMORYERROR); pix = pixBuf->Ptr(); pal = palBuf->Ptr(); if( (!pix) || (!pal) ) ProcessImageIOError(&bi,BMMRES_MEMORYERROR); if( Storage()->Paletted()) { //-- Existing map is palletted...so get the pallete and //-- the look up table..we are done.. Storage()->GetPalette(0, 256, pal); for(y = 0; y < h; y++) Storage()->GetIndexPixels(0,(h-y-1),w,pix+wb*y); } else { //-- Caluculate the pallete for the image.. //-- Then create the look up table if(CalcOutputPalette(256,pal) == 0) ProcessImageIOError(&bi); PixelBuf64 line(w); ColorPacker* cPack = BMMNewColorPacker(w,pal,256); for(y=0; y<h; y++) { if(!GetOutputPixels(0,(h-y-1),w,line.Ptr())) ProcessImageIOError(&bi); cPack->PackLine(line.Ptr(),pix+y*wb,w); } cPack->DeleteThis(); } //-- Fill in the BITMAPINFO structure--------------------- lx = sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD) + wb*h; pbmi = (PBITMAPINFO)LocalAlloc(LPTR,lx); if (!pbmi) return (ProcessImageIOError(&bi,GetString(IDS_CONVERT_ERROR))); memset(pbmi,0,lx); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = w; pbmi->bmiHeader.biHeight = h; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = 8; pbmi->bmiHeader.biCompression = BI_RGB; pbmi->bmiHeader.biSizeImage = w*h; //256*sizeof(RGBQUAD) + wb*h; pbmi->bmiHeader.biXPelsPerMeter = 2834; pbmi->bmiHeader.biYPelsPerMeter = 2834; hdr.bfOffBits += 256*sizeof(RGBQUAD); // DS 2/16/98 RGBQUAD *rgb; //-- Fill in the palette rgb = (RGBQUAD*) &(pbmi->bmiColors[0]); for(y=0; y<256; y++) { rgb->rgbRed = pal[y].r >> 8; rgb->rgbGreen = pal[y].g >> 8; rgb->rgbBlue = pal[y].b >> 8; rgb++; } //-- Fill in the look up table memcpy((LPBYTE)rgb, pix,wb*h); break; //-- RGB24 requested-------------------------------------- case BMM_NO_TYPE: case BMM_TRUE_24: { //-- Convert Bitmap to DIB --------------------------- pbmi = GetDitheredOutputDib(); if (!pbmi) return (ProcessImageIOError(&bi,GetString(IDS_CONVERT_ERROR))); //-- Prepare Header ------------------------ if (bi.GetUpdateWindow()) SendMessage(bi.GetUpdateWindow(),BMM_PROGRESS,25,100); int rb = (map->Width() * 3 + 3) & ~3; // must be multiple of 4 bytes lx = sizeof(BITMAPINFOHEADER) + (rb * map->Height()); } break; default: assert(0); return BMMRES_IOERROR; break; } hdr.bfSize = lx + sizeof(BITMAPFILEHEADER); //-- Write Header ------------------------ size_t res = fwrite(&hdr,1,sizeof(BITMAPFILEHEADER),file.stream); if (res != sizeof(BITMAPFILEHEADER)) { io_error: result = ProcessImageIOError(&bi); LocalFree(pbmi); return (result); } //-- Write Image File -------------------------------- if (bi.GetUpdateWindow()) SendMessage(bi.GetUpdateWindow(),BMM_PROGRESS,50,100); res = fwrite(pbmi,1,lx,file.stream); if (res != lx) goto io_error; LocalFree(pbmi); if (bi.GetUpdateWindow()) SendMessage(bi.GetUpdateWindow(),BMM_PROGRESS,100,100); return (result); }
BitmapStorage * BitmapIO_EPS::Load (BitmapInfo *fbi, Bitmap *map, BMMRES *status) { *status = ProcessImageIOError(fbi,BMMRES_INTERNALERROR); return (NULL); }
BMMRES BitmapIO_PNG::Save(const TCHAR *filename, Bitmap *map) { if(!map) return(ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); openMode = BMM_OPEN_W; if((ostream = _tfopen(filename,_T("wb"))) == NULL) return (ProcessImageIOError(&bi)); BitmapStorage *palettedStorage = NULL; png = png_create_write_struct (PNG_VERSION, (void *) this, error_func, warning_func); if (setjmp(png->jmpbuf)) { if (info) for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } if (palettedStorage) delete palettedStorage; fclose(ostream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } info = png_create_info_struct(png); png_init_io(png, ostream); switch(cfg.color_type) { case PngPalette: info->color_type = PNG_COLOR_TYPE_PALETTE; info->pixel_depth = 8; info->valid |= PNG_INFO_PLTE; info->num_palette = 256; break; case PngRGB: info->color_type = PNG_COLOR_TYPE_RGB; break; case PngRGBA: info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; case PngGray: info->color_type = PNG_COLOR_TYPE_GRAY; break; case PngGrayA: info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break; } info->width = map->Width(); info->height = map->Height(); if (OutputGamma() != 1.0f) { info->valid |= PNG_INFO_gAMA; info->gamma = OutputGamma(); } else info->gamma = 1.0f; if (map->Aspect() != 1.0f) { info->valid |= PNG_INFO_pHYs; info->x_pixels_per_unit = (png_uint_32)(1024.0f * map->Aspect()); info->y_pixels_per_unit = 1024; info->phys_unit_type = 0; } if (cfg.interlaced) info->interlace_type = 1; else info->interlace_type = 0; switch( info->color_type) { case PNG_COLOR_TYPE_PALETTE: case PNG_COLOR_TYPE_GRAY: info->channels = 1; break; case PNG_COLOR_TYPE_GRAY_ALPHA: info->channels = 2; break; case PNG_COLOR_TYPE_RGB: info->channels = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: info->channels = 4; break; } info->bit_depth = cfg.bitdepth; info->rowbytes = info->width * info->channels * info->bit_depth / 8; row_pointers = (png_bytep *)malloc(info->height * sizeof(png_bytep)); for (png_uint_32 i = 0; i < info->height; i++) row_pointers[i] = (png_bytep)malloc(info->rowbytes); switch (info->bit_depth) { case 16: // this is only RGB/RGBA/Gray/GrayA switch(info->color_type) { case PNG_COLOR_TYPE_RGB: case PNG_COLOR_TYPE_RGB_ALPHA: { BMM_Color_64 *line64 = (BMM_Color_64 *) calloc(info->width,sizeof(BMM_Color_64)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (GetOutputPixels(0, iy, info->width, line64) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(ostream); _tremove(filename); free(line64); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } BMM_Color_64 *l64=line64; unsigned short *oshort = (unsigned short *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ++l64, ix++) { *oshort = (unsigned short)l64->r; oshort++; *oshort = (unsigned short)l64->g; oshort++; *oshort = (unsigned short)l64->b; oshort++; if (info->channels == 4) { *oshort = (unsigned short)l64->a; oshort++; } } } free(line64); } break; case PNG_COLOR_TYPE_GRAY: { for (png_uint_32 iy = 0; iy < info->height; ++iy) if (map->Get16Gray(0, iy, info->width, (unsigned short *)row_pointers[iy]) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(ostream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } } break; case PNG_COLOR_TYPE_GRAY_ALPHA: { BMM_Color_64 *line64 = (BMM_Color_64 *) calloc(info->width, sizeof(BMM_Color_64)); unsigned short *line = (unsigned short *) calloc(info->width, sizeof(unsigned short)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (GetOutputPixels(0, iy, info->width, line64) != 1 || map->Get16Gray(0, iy, info->width, line) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } free(line64); free(line); fclose(ostream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } BMM_Color_64 *l64 = line64; unsigned short *l=line; unsigned short *oshort = (unsigned short *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ix++, l64++) { *oshort++ = *l++; *oshort++ = (unsigned short)l64->a; } } free(line64); free(line); } break; } break; case 8: // this can be any type switch(info->color_type) { case PNG_COLOR_TYPE_PALETTE: { // Set up a palette buffer PixelBuf48 palettebuf(info->num_palette); BMM_Color_48 *pal = palettebuf.Ptr(); // Must compute a color palette, and reduce the image to 256 colors! // this calculates a palette based on the gamma corrected values, which // corresponds to what GetOutputPixels returns. if(CalcOutputPalette(256, pal) == 0) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(ostream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } info->palette = (png_color *)malloc(info->num_palette * sizeof(png_color)); for (int i = 0; i < info->num_palette; i++) { info->palette[i].red = (unsigned char)(pal[i].r >> 8); info->palette[i].green = (unsigned char)(pal[i].g >> 8); info->palette[i].blue = (unsigned char)(pal[i].b >> 8); } PixelBuf64 line(info->width); ColorPacker* cpack = BMMNewColorPacker(info->width, pal, info->num_palette); for (png_uint_32 iy=0; iy < info->height; ++iy) { if(!GetOutputPixels(0, iy, info->width, line.Ptr())) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(ostream); _tremove(filename); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } cpack->PackLine(line.Ptr(), row_pointers[iy], info->width); } cpack->DeleteThis(); } break; case PNG_COLOR_TYPE_RGB: case PNG_COLOR_TYPE_RGB_ALPHA: { BMM_Color_32 *line32 = (BMM_Color_32 *) calloc(info->width,sizeof(BMM_Color_32)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (GetDitheredOutputPixels(0, iy, info->width, line32) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(ostream); _tremove(filename); free(line32); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } BMM_Color_32 *l32=line32; unsigned char *obyte = (unsigned char *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ++l32, ix++) { *obyte = (unsigned char)l32->r; obyte++; *obyte = (unsigned char)l32->g; obyte++; *obyte = (unsigned char)l32->b; obyte++; if (info->channels == 4) { *obyte = (unsigned char)l32->a; obyte++; } } } free(line32); } break; case PNG_COLOR_TYPE_GRAY: { unsigned short *line = (unsigned short *) calloc(info->width * info->channels, sizeof(unsigned short)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (map->Get16Gray(0, iy, info->width, line) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(ostream); _tremove(filename); free(line); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } unsigned short *l=line; unsigned char *obyte = (unsigned char *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ix++) { *obyte++ = (unsigned char)(*l >> 8); l++; } } free(line); } break; case PNG_COLOR_TYPE_GRAY_ALPHA: { BMM_Color_64 *line64 = (BMM_Color_64 *) calloc(info->width,sizeof(BMM_Color_64)); unsigned short *line = (unsigned short *) calloc(info->width, sizeof(unsigned short)); for (png_uint_32 iy = 0; iy < info->height; ++iy) { if (GetOutputPixels(0, iy, info->width, line64) != 1 || map->Get16Gray(0, iy, info->width, line) != 1) { for (png_uint_32 i = 0; i < info->height; i++) if (row_pointers[i]) free(row_pointers[i]); if (row_pointers) { free(row_pointers); row_pointers = NULL; } fclose(ostream); _tremove(filename); free(line); free(line64); png_destroy_write_struct (&png, &info); return BMMRES_IOERROR; } unsigned short *l=line; BMM_Color_64 *l64 = line64; unsigned char *obyte = (unsigned char *)row_pointers[iy]; for (png_uint_32 ix = 0; ix < info->width; ix++, l64++) { *obyte++ = (unsigned char)(*l >> 8); l++; *obyte++ = (unsigned char)(l64->a >> 8); } } free(line); free(line64); } break; } break; #ifdef OUTPUT_1_2_4 case 4: { // Paletted only } break; case 2: { // Paletted only } break; case 1: { // Paletted only } #endif break; } png_write_info(png, info); png_set_swap(png); png_write_image(png, row_pointers); png_write_end(png, info); fclose(ostream); for (i = 0; i < info->height; i++) free(row_pointers[i]); free(row_pointers); png_destroy_write_struct (&png, &info); return BMMRES_SUCCESS; }
//FIXME BitmapStorage* BitmapIO_CIN::Load(BitmapInfo* bmi, Bitmap* bm, unsigned short* status) { BitmapStorage* bms = NULL; File file(bmi->Name(), _T("rb")); *status = BMMRES_SUCCESS; if (!file.mStream) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_File_Open_Error)); return NULL; } mStream = file.mStream; if (openMode != BMM_NOT_OPEN) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Internal_Error)); return NULL; } CineonFile cineonImage(mStream); if (cineonImage.VerifyHeader() == FALSE) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Invalid_Header_Error)); return NULL; } if (!cineonImage.IsSupported()) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Unsupported_File_Error)); return NULL; } unsigned int pixelsPL = cineonImage.GetPixelsPerLine(); unsigned int linesPI = cineonImage.GetLinesPerImage(); bmi->SetWidth(pixelsPL); bmi->SetHeight(linesPI); // bmi->SetGamma(cineonImage.GetImageGamma()); // bmi->SetAspect(); bmi->SetFirstFrame(0); bmi->SetLastFrame(0); // bmi->SetFlags(MAP_NOFLAGS); bms = BMMCreateStorage(bm->Manager(), BMM_TRUE_64); if (!bms) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Internal_Error)); return NULL; } if (!(bms->Allocate(bmi, bm->Manager(), BMM_OPEN_R))) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Memory_Error)); delete bms; bms = NULL; return NULL; } BMM_Color_64* scanLine = (BMM_Color_64*) calloc(pixelsPL, sizeof(BMM_Color_64)); if (!scanLine) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Memory_Error)); if (bms) { delete bms; bms = NULL; } return NULL; } if (!cineonImage.SetLUTs(10, (float) mUserData.mRefWhite, (float) mUserData.mRefBlack)) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Memory_Error)); if (bms) { delete bms; bms = NULL; } return NULL; } for (unsigned int cnt = 0; cnt < linesPI; cnt++) { // 4 WORD Channels if (!cineonImage.GetScanLine((unsigned short*)scanLine, cnt, pixelsPL)) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_File_IO_Error)); if (bms) { delete bms; bms = NULL; } if (scanLine) { free(scanLine); scanLine = NULL; } return NULL; } // test colors ~ 5sec 1828x1332 /* float r1 = ((float) cnt) / ((float) linesPI); for (unsigned int i = 0; i < pixelsPL; i++) { float r2 = ((float) i) / ((float) pixelsPL); scanLine[i].r = (int) (65535.f * r1); scanLine[i].g = (int) (65535.f * r2); scanLine[i].b = (int) (65535.f * (r1 * r2)); scanLine[i].a = 0; //CIN has no alpha } */ if (!bms->PutPixels(0, cnt, pixelsPL, scanLine)) { *status = ProcessImageIOError(bmi, GetResIDCaption(IDS_CIN_Internal_Error)); if (bms) { delete bms; bms = NULL; } if (scanLine) { free(scanLine); scanLine = NULL; } return NULL; } } if (scanLine) { free(scanLine); scanLine = NULL; } openMode = BMM_OPEN_R; return bms; }
BitmapStorage *BitmapIO_GIF::ReadGIFFile(BitmapInfo *fbi, BitmapManager *manager, BMMRES *status) { BitmapStorage *s = NULL; File file(fbi->Name(), _T("rb")); // Init all class vars loadMap = NULL; loadStorage = saveStorage = NULL; inStream = outStream = NULL; badGIFReason = 0; bad_code_count = 0; gif_line = 0; gif_colors = 0; iphase = 0; iy = 0; curr_size = 0; clear = 0; ending = 0; newcodes = 0; top_slot = 0; slot = 0; navail_bytes = 0; nbits_left = 0; b1 = 0; pbytes = NULL; for(int i = 0; i < 259; ++i) gif_byte_buff[i] = 0; gif_wpt = NULL; gif_wcount = 0; prior_codes = NULL; code_ids = NULL; added_chars = NULL; code_size = 0; clear_code = 0; eof_code = 0; bit_offset = 0; max_code = 0; free_code = 0; inStream = file.stream; if(inStream == NULL) { *status = ProcessImageIOError(fbi); return NULL; } if (ReadHeader()) { fbi->SetWidth (image.w); fbi->SetHeight(image.h); // fbi->SetGamma (1.0f); fbi->SetAspect(1.0f); fbi->SetFirstFrame(0); fbi->SetLastFrame(0); fbi->SetType(storageType); #ifdef DBG_GIF DebugPrint(_T("Image info: W:%d H:%d FLAGS:%X\n"), image.w,image.h,image.flags); #endif // DBG_GIF s = LoadGIFStuff(fbi, manager); if(s) return s; //-- If we get here, something went wrong! *status = ProcessImageIOError(fbi,BMMRES_INVALIDFORMAT); return NULL; } //-- If we get here, something went wrong! *status = ProcessImageIOError(fbi,BMMRES_BADFILEHEADER); return NULL; }
BitmapStorage *BitmapIO_YUV::Load(BitmapInfo *fbi, Bitmap *map, BMMRES *status) { unsigned char *yuvbuf = NULL; BMM_Color_64 *rgbbuf = NULL; BitmapStorage *s = NULL; //-- Initialize Status Optimistically *status = BMMRES_SUCCESS; //-- Make sure nothing weird is going on if(openMode != BMM_NOT_OPEN) { *status = ProcessImageIOError(fbi,BMMRES_INTERNALERROR); return NULL; } //-- Update Bitmap Info *status = GetImageInfo(fbi); if (*status != BMMRES_SUCCESS) return(NULL); //-- Open YUV File ----------------------------------- File file(fbi->Name(), _T("rb")); inStream = file.stream; if (inStream == NULL) { *status = ProcessImageIOError(fbi); return NULL; } //-- Create Image Storage ---------------------------- s = BMMCreateStorage(map->Manager(),BMM_TRUE_32); if(!s) { *status = ProcessImageIOError(fbi,BMMRES_INTERNALERROR); return NULL; } //-- Allocate Image Storage -------------------------- if (s->Allocate(fbi,map->Manager(),BMM_OPEN_R)==0) { memory_error_out: *status = ProcessImageIOError(fbi,BMMRES_MEMORYERROR); goto bail_out; io_error_out: *status = ProcessImageIOError(fbi); bail_out: if (s) delete s; if (yuvbuf) free(yuvbuf); if (rgbbuf) free(rgbbuf); return NULL; } //-- Allocate Buffers -------------------------------- yuvbuf=(unsigned char *)malloc(fbi->Width()*2); rgbbuf=(BMM_Color_64 *)malloc(fbi->Width()*sizeof(BMM_Color_64)); if(!yuvbuf || !rgbbuf) goto memory_error_out; //-- Read Image INT_PTR pixels = fbi->Width() * fbi->Height(); int rows = 0; while (pixels) { pixels = fread(yuvbuf,2,fbi->Width(),inStream); if (pixels != fbi->Width() && pixels != 0) { goto io_error_out; } if (pixels) { YUVtoRGB(rgbbuf,yuvbuf,fbi->Width()); if (s->PutPixels(0,rows,fbi->Width(),rgbbuf)!=1) goto io_error_out; rows++; if (rows>fbi->Height()) break; } //-- Progress Report if (fbi->GetUpdateWindow()) SendMessage(fbi->GetUpdateWindow(),BMM_PROGRESS,rows,fbi->Height()); } if (yuvbuf) free(yuvbuf); if (rgbbuf) free(rgbbuf); //-- Set the storage's BitmapInfo s->bi.CopyImageInfo(fbi); return s; }