int imFileFormatJP2::WriteImageData(void* data) { int count = imFileLineBufferCount(this); imCounterTotal(this->counter, count, "Writing JP2..."); /* first time count */ int depth = imColorModeDepth(this->file_color_mode); if (imColorModeHasAlpha(this->user_color_mode) && imColorModeHasAlpha(this->file_color_mode)) { jas_image_setcmpttype(image, depth-1, JAS_IMAGE_CT_OPACITY); depth--; } for (int d = 0; d < depth; d++) jas_image_setcmpttype(image, d, JAS_IMAGE_CT_COLOR(d)); int row = 0, plane = 0; for (int i = 0; i < count; i++) { imFileLineBufferWrite(this, data, row, plane); int ret = 1; if (this->file_data_type == IM_BYTE) ret = iJP2WriteLine(image, row, plane, (imbyte*)this->line_buffer); else ret = iJP2WriteLine(image, row, plane, (imushort*)this->line_buffer); if (!ret) return IM_ERR_ACCESS; if (!imCounterInc(this->counter)) return IM_ERR_COUNTER; imFileLineBufferInc(this, &row, &plane); } char outopts[512] = ""; imAttribTable* attrib_table = AttribTable(); float* ratio = (float*)attrib_table->Get("CompressionRatio"); if (ratio) sprintf(outopts, "rate=%g", (double)(1.0 / *ratio)); // The counter continuous because in Jasper all image writing is done here. BAD! ijp2_counter = this->counter; ijp2_abort = 0; ijp2_message = NULL; /* other counts */ int err = jas_image_encode(image, stream, 0 /*JP2 format always */, outopts); ijp2_counter = -1; if (err) return IM_ERR_ACCESS; jas_stream_flush(stream); return IM_ERR_NONE; }
int imFileFormatRAW::iRawUpdateParam(int index) { (void)index; imAttribTable* attrib_table = AttribTable(); // update image count int* icount = (int*)attrib_table->Get("ImageCount"); if (icount) this->image_count = *icount; else this->image_count = 1; // update file byte order int* byte_order = (int*)attrib_table->Get("ByteOrder"); if (byte_order) imBinFileByteOrder(this->handle, *byte_order); // position at start offset, the default is at 0 int* start_offset = (int*)attrib_table->Get("StartOffset"); if (!start_offset) imBinFileSeekOffset(this->handle, 0); else imBinFileSeekOffset(this->handle, *start_offset); if (imBinFileError(this->handle)) return IM_ERR_ACCESS; int* stype = (int*)attrib_table->Get("SwitchType"); if (stype) this->switch_type = *stype; // The following attributes MUST exist this->width = *(int*)attrib_table->Get("Width"); this->height = *(int*)attrib_table->Get("Height"); this->file_color_mode = *(int*)attrib_table->Get("ColorMode"); this->file_data_type = *(int*)attrib_table->Get("DataType"); int* pad = (int*)attrib_table->Get("Padding"); if (pad) { int line_size = imImageLineSize(this->width, this->file_color_mode, this->file_data_type); if (this->switch_type && (this->file_data_type == IM_FLOAT || this->file_data_type == IM_CFLOAT)) line_size *= 2; this->padding = iCalcPad(*pad, line_size); } return IM_ERR_NONE; }
int imFileFormatSGI::WriteImageInfo() { unsigned int dword_value; unsigned short word_value; unsigned char dummy[404]; memset(dummy, 0, 404); this->comp_type = SGI_VERBATIM; if (imStrEqual(this->compression, "RLE")) this->comp_type = SGI_RLE; unsigned int color_map_id = SGI_NORMAL; this->file_color_mode = imColorModeSpace(this->user_color_mode); int dimension = 2; if (this->file_color_mode == IM_BINARY) this->convert_bpp = -1; // expand 1 to 255 else if (this->file_color_mode == IM_RGB) { dimension = 3; if (imColorModeHasAlpha(this->user_color_mode)) this->file_color_mode |= IM_ALPHA; } this->file_data_type = this->user_data_type; this->bpc = 1; int max = 255; if (this->file_data_type == IM_USHORT) { max = 65535; this->bpc = 2; } this->starttab = NULL; this->lengthtab = NULL; /* writes the SGI file header */ word_value = SGI_ID; imBinFileWrite(handle, &word_value, 1, 2); /* identifier */ imBinFileWrite(handle, &this->comp_type, 1, 1); /* storage */ imBinFileWrite(handle, &this->bpc, 1, 1); /* bpc */ word_value = (imushort)dimension; imBinFileWrite(handle, &word_value, 1, 2); /* dimension */ word_value = (unsigned short)this->width; imBinFileWrite(handle, &word_value, 1, 2); /* image width */ word_value = (unsigned short)this->height; imBinFileWrite(handle, &word_value, 1, 2); /* image height */ word_value = (imushort)imColorModeDepth(this->file_color_mode); imBinFileWrite(handle, &word_value, 1, 2); /* depth */ dword_value = 0; imBinFileWrite(handle, &dword_value, 1, 4); /* min */ dword_value = max; imBinFileWrite(handle, &dword_value, 1, 4); /* max */ imBinFileWrite(handle, dummy, 4, 1); /* dummy */ /* tests if everything was ok */ if (imBinFileError(handle)) return IM_ERR_ACCESS; int size; char* image_name = (char*)AttribTable()->Get("Description", NULL, &size); if (image_name) { if (size < 80) { imBinFileWrite(handle, image_name, size, 1); imBinFileWrite(handle, dummy, 80-size, 1); } else { imBinFileWrite(handle, image_name, 79, 1); imBinFileWrite(handle, (void*)"\0", 1, 1); } } else imBinFileWrite(handle, dummy, 80, 1); /* empty image name */ dword_value = color_map_id; imBinFileWrite(handle, &dword_value, 1, 4); /* color_map_id */ imBinFileWrite(handle, dummy, 404, 1); /* dummy */ /* tests if everything was ok */ if (imBinFileError(handle)) return IM_ERR_ACCESS; if (this->comp_type == SGI_RLE) { int tablen = this->height * imColorModeDepth(this->file_color_mode); this->starttab = (unsigned int *)malloc(tablen*4); this->lengthtab = (unsigned int *)malloc(tablen*4); /* writes the empty compression control information */ /* we will write again at the end */ imBinFileWrite(handle, this->starttab, tablen*4, 1); imBinFileWrite(handle, this->lengthtab, tablen*4, 1); // allocates more than enough since compression algoritm can be ineficient this->line_buffer_extra = 2*imImageLineSize(this->width, this->file_color_mode, this->file_data_type); } /* tests if everything was ok */ if (imBinFileError(handle)) return IM_ERR_ACCESS; return IM_ERR_NONE; }
int imFileFormatSGI::ReadImageInfo(int index) { (void)index; unsigned short word_value, dimension, depth; /* reads the number of bits per channel */ imBinFileRead(handle, &this->bpc, 1, 1); /* reads the number of dimensions */ imBinFileRead(handle, &dimension, 1, 2); /* reads the image width */ imBinFileRead(handle, &word_value, 1, 2); this->width = word_value; /* reads the image height */ imBinFileRead(handle, &word_value, 1, 2); this->height = word_value; /* reads the number of channels */ imBinFileRead(handle, &depth, 1, 2); /* jump 12 bytes (min, max, dummy) */ imBinFileSeekOffset(handle, 12); /* reads the image name */ char image_name[80]; imBinFileRead(handle, image_name, 80, 1); if (image_name[0] != 0) AttribTable()->Set("Description", IM_BYTE, imStrNLen(image_name, 80)+1, image_name); /* reads the color map information */ unsigned int color_map_id; imBinFileRead(handle, &color_map_id, 1, 4); if (imBinFileError(handle)) return IM_ERR_ACCESS; this->file_data_type = IM_BYTE; if (this->bpc == 2) this->file_data_type = IM_USHORT; switch (dimension) { case 1: this->height = 1; depth = 1; case 2: depth = 1; break; case 3: break; default: return IM_ERR_DATA; } switch (color_map_id) { case SGI_NORMAL: switch(depth) { case 1: this->file_color_mode = IM_GRAY; break; case 3: this->file_color_mode = IM_RGB; break; case 4: this->file_color_mode = IM_RGB | IM_ALPHA; break; default: return IM_ERR_DATA; } break; case SGI_DITHERED: this->file_color_mode = IM_MAP; break; case SGI_COLORMAP: this->file_color_mode = IM_RGB; break; case SGI_SCREEN: this->file_color_mode = IM_GRAY; break; default: return IM_ERR_DATA; } /* jump 404 bytes (dummy) */ imBinFileSeekOffset(handle, 404); if (this->comp_type == SGI_RLE) { int tablen = this->height * depth; this->starttab = (unsigned int *)malloc(tablen * sizeof(int)); this->lengthtab = (unsigned int *)malloc(tablen * sizeof(int)); /* reads the compression control information */ imBinFileRead(handle, this->starttab, tablen, 4); imBinFileRead(handle, this->lengthtab, tablen, 4); // allocates more than enough since compression algoritm can be ineficient this->line_buffer_extra = 2*imImageLineSize(this->width, this->file_color_mode, this->file_data_type); } if (imBinFileError(handle)) return IM_ERR_ACCESS; if (color_map_id == SGI_DITHERED) { static int red[8] = {0, 36, 73, 109, 146, 182, 218, 255}; static int green[8] = {0, 36, 73, 109, 146, 182, 218, 255}; static int blue[4] = {0, 85, 170, 255}; int c = 0; for (int b = 0; b < 4; b++) { for (int g = 0; g < 8; g++) { for (int r = 0; r < 8; r++) { this->palette[c] = imColorEncode((imbyte)red[r], (imbyte)green[g], (imbyte)blue[b]); c++; } } } } return IM_ERR_NONE; }
int imFileFormatJPEG::WriteImageInfo() { this->file_color_mode = imColorModeSpace(this->user_color_mode); this->file_color_mode |= IM_TOPDOWN; if (imColorModeDepth(this->file_color_mode) > 1) this->file_color_mode |= IM_PACKED; this->file_data_type = IM_BYTE; /* Step 3: set parameters for compression */ this->cinfo.image_width = this->width; /* image width and height, in pixels */ this->cinfo.image_height = this->height; this->cinfo.input_components = imColorModeDepth(this->file_color_mode); switch (imColorModeSpace(this->user_color_mode)) { case IM_BINARY: this->convert_bpp = -1; // expand 1 to 255 case IM_GRAY: this->cinfo.in_color_space = JCS_GRAYSCALE; break; case IM_RGB: this->cinfo.in_color_space = JCS_RGB; break; case IM_CMYK: this->cinfo.in_color_space = JCS_CMYK; break; case IM_YCBCR: this->cinfo.in_color_space = JCS_YCbCr; break; default: this->cinfo.in_color_space = JCS_UNKNOWN; break; } if (setjmp(this->jerr.setjmp_buffer)) return IM_ERR_ACCESS; jpeg_set_defaults(&this->cinfo); imAttribTable* attrib_table = AttribTable(); int* auto_ycbcr = (int*)attrib_table->Get("AutoYCbCr"); if (auto_ycbcr && *auto_ycbcr == 0 && this->cinfo.in_color_space == JCS_RGB) { jpeg_set_colorspace(&this->cinfo, JCS_RGB); } int* interlaced = (int*)attrib_table->Get("Interlaced"); if (interlaced && *interlaced) jpeg_simple_progression(&this->cinfo); int* quality = (int*)attrib_table->Get("JPEGQuality"); if (quality) jpeg_set_quality(&this->cinfo, *quality, TRUE); char* res_unit = (char*)attrib_table->Get("ResolutionUnit"); if (res_unit) { float* xres = (float*)attrib_table->Get("XResolution"); float* yres = (float*)attrib_table->Get("YResolution"); if (xres && yres) { if (imStrEqual(res_unit, "DPI")) this->cinfo.density_unit = 1; else this->cinfo.density_unit = 2; this->cinfo.X_density = (UINT16)*xres; this->cinfo.Y_density = (UINT16)*yres; } } /* Step 4: Start compressor */ jpeg_start_compress(&this->cinfo, TRUE); int desc_size; char* desc = (char*)attrib_table->Get("Description", NULL, &desc_size); if (desc) jpeg_write_marker(&this->cinfo, JPEG_COM, (JOCTET*)desc, desc_size-1); #ifdef USE_EXIF iWriteExifAttrib(attrib_table); #endif return IM_ERR_NONE; }
int imFileFormatJPEG::ReadImageInfo(int index) { (void)index; this->fix_adobe_cmyk = 0; if (setjmp(this->jerr.setjmp_buffer)) return IM_ERR_ACCESS; // notify libjpeg to save the COM marker jpeg_save_markers(&this->dinfo, JPEG_COM, 0xFFFF); jpeg_save_markers(&this->dinfo, JPEG_APP0+1, 0xFFFF); /* Step 3: read file parameters with jpeg_read_header() */ if (jpeg_read_header(&this->dinfo, TRUE) != JPEG_HEADER_OK) return IM_ERR_ACCESS; this->width = this->dinfo.image_width; this->height = this->dinfo.image_height; this->file_data_type = IM_BYTE; switch(this->dinfo.jpeg_color_space) { case JCS_GRAYSCALE: this->file_color_mode = IM_GRAY; break; case JCS_RGB: this->file_color_mode = IM_RGB; break; case JCS_YCbCr: this->file_color_mode = IM_RGB; break; case JCS_CMYK: this->file_color_mode = IM_CMYK; if (this->dinfo.saw_Adobe_marker) this->fix_adobe_cmyk = 1; break; case JCS_YCCK: this->file_color_mode = IM_CMYK; this->dinfo.out_color_space = JCS_CMYK; // this is the only supported conversion in libjpeg if (this->dinfo.saw_Adobe_marker) this->fix_adobe_cmyk = 1; break; default: /* JCS_UNKNOWN */ return IM_ERR_DATA; } imAttribTable* attrib_table = AttribTable(); int* auto_ycbcr = (int*)attrib_table->Get("AutoYCbCr"); if (auto_ycbcr && *auto_ycbcr == 0 && this->dinfo.jpeg_color_space == JCS_YCbCr) { this->file_color_mode = IM_YCBCR; this->dinfo.out_color_space = JCS_YCbCr; } this->file_color_mode |= IM_TOPDOWN; if (imColorModeDepth(this->file_color_mode) > 1) this->file_color_mode |= IM_PACKED; if (this->dinfo.progressive_mode != 0) { int progressive = 1; attrib_table->Set("Interlaced", IM_INT, 1, &progressive); } if (this->dinfo.density_unit != 0) { float xres = (float)this->dinfo.X_density, yres = (float)this->dinfo.Y_density; if (this->dinfo.density_unit == 1) attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPI"); else attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPC"); attrib_table->Set("XResolution", IM_FLOAT, 1, (void*)&xres); attrib_table->Set("YResolution", IM_FLOAT, 1, (void*)&yres); } if (this->dinfo.marker_list) { jpeg_saved_marker_ptr cur_marker = this->dinfo.marker_list; // search for COM marker while (cur_marker) { if (cur_marker->marker == JPEG_COM) { char* desc = new char [cur_marker->data_length+1]; memcpy(desc, cur_marker->data, cur_marker->data_length); desc[cur_marker->data_length] = 0; attrib_table->Set("Description", IM_BYTE, cur_marker->data_length+1, desc); delete [] desc; } #ifdef USE_EXIF if (cur_marker->marker == JPEG_APP0+1) iReadExifAttrib(cur_marker->data, cur_marker->data_length, attrib_table); #endif cur_marker = cur_marker->next; } } /* Step 5: Start decompressor */ if (jpeg_start_decompress(&this->dinfo) == FALSE) return IM_ERR_ACCESS; return IM_ERR_NONE; }
int imFileFormatJP2::WriteImageInfo() { this->file_data_type = this->user_data_type; this->file_color_mode = imColorModeSpace(this->user_color_mode); this->file_color_mode |= IM_TOPDOWN; int prec = 8; if (this->file_data_type == IM_USHORT) prec = 16; jas_clrspc_t clrspc; switch (imColorModeSpace(this->user_color_mode)) { case IM_BINARY: prec = 1; case IM_GRAY: clrspc = JAS_CLRSPC_SGRAY; break; case IM_RGB: clrspc = JAS_CLRSPC_SRGB; break; case IM_XYZ: clrspc = JAS_CLRSPC_CIEXYZ; break; case IM_LAB: clrspc = JAS_CLRSPC_CIELAB; break; case IM_YCBCR: clrspc = JAS_CLRSPC_SYCBCR; break; default: return IM_ERR_DATA; } if (imColorModeHasAlpha(this->user_color_mode)) this->file_color_mode |= IM_ALPHA; int numcmpts = imColorModeDepth(this->file_color_mode); jas_image_cmptparm_t cmptparms[4]; for (int i = 0; i < numcmpts; i++) { jas_image_cmptparm_t* cmptparm = &cmptparms[i]; cmptparm->tlx = 0; cmptparm->tly = 0; cmptparm->hstep = 1; cmptparm->vstep = 1; cmptparm->width = this->width; cmptparm->height = this->height; cmptparm->prec = prec; cmptparm->sgnd = 0; } this->image = jas_image_create(numcmpts, cmptparms, clrspc); if (!this->image) return IM_ERR_DATA; if (this->image->metadata.count > 0) { const void* data; int size; imAttribTable* attrib_table = AttribTable(); // GeoTIFF first data = attrib_table->Get("GeoTIFFBox", NULL, &size); if (data) { jas_metadata_box_t *metabox = &image->metadata.boxes[JAS_IMAGE_BOX_GEO]; jas_box_alloc(metabox, size); memcpy(metabox->buf, data, size); memcpy(metabox->id, msi_uuid, sizeof(msi_uuid)); } // Adobe XMP data = attrib_table->Get("XMLPacket", NULL, &size); if (data) { jas_metadata_box_t *metabox = &image->metadata.boxes[JAS_IMAGE_BOX_XMP]; jas_box_alloc(metabox, size); memcpy(metabox->buf, data, size); memcpy(metabox->id, xmp_uuid, sizeof(xmp_uuid)); } } return IM_ERR_NONE; }
int imFileFormatJP2::ReadImageInfo(int index) { (void)index; // The counter is started because in Jasper all image reading is done here. BAD! ijp2_counter = this->counter; ijp2_abort = 0; ijp2_message = "Reading JP2..."; this->image = jas_image_decode(this->stream, this->fmtid, 0); ijp2_counter = -1; if (!this->image) return IM_ERR_ACCESS; this->width = jas_image_width(this->image); this->height = jas_image_height(this->image); int clrspc_fam = jas_clrspc_fam(jas_image_clrspc(image)); switch(clrspc_fam) { case JAS_CLRSPC_FAM_GRAY: this->file_color_mode = IM_GRAY; break; case JAS_CLRSPC_FAM_XYZ: this->file_color_mode = IM_XYZ; break; case JAS_CLRSPC_FAM_RGB: this->file_color_mode = IM_RGB; break; case JAS_CLRSPC_FAM_YCBCR: this->file_color_mode = IM_YCBCR; break; case JAS_CLRSPC_FAM_LAB: this->file_color_mode = IM_LAB; break; default: return IM_ERR_DATA; } this->file_data_type = IM_BYTE; int prec = jas_image_cmptprec(image, 0); if (prec > 8) this->file_data_type = IM_USHORT; if (prec < 8) this->convert_bpp = -prec; // just expand to 0-255 if (prec == 1 && this->file_color_mode == IM_GRAY) this->file_color_mode = IM_BINARY; int cmpno = jas_image_getcmptbytype(this->image, JAS_IMAGE_CT_OPACITY); if (cmpno != -1) this->file_color_mode |= IM_ALPHA; this->file_color_mode |= IM_TOPDOWN; if (image->metadata.count > 0) { imAttribTable* attrib_table = AttribTable(); // First write GeoTIFF data jas_metadata_box_t *metabox = &image->metadata.boxes[JAS_IMAGE_BOX_GEO]; if (metabox->size>0 && metabox->buf) attrib_table->Set("GeoTIFFBox", IM_BYTE, metabox->size, metabox->buf); // Check if XMP is there metabox = &image->metadata.boxes[JAS_IMAGE_BOX_XMP]; if (metabox->size>0 && metabox->buf) attrib_table->Set("XMLPacket", IM_BYTE, metabox->size, metabox->buf); } return IM_ERR_NONE; }
int imFileFormatAVI::WriteImageInfo() { if (dib) { if (dib->bmih->biWidth != width || dib->bmih->biHeight != height || imColorModeSpace(file_color_mode) != imColorModeSpace(user_color_mode)) return IM_ERR_DATA; return IM_ERR_NONE; // parameters can be set only once } // force bottom up orientation this->file_data_type = IM_BYTE; this->file_color_mode = imColorModeSpace(this->user_color_mode); int bpp; if (this->file_color_mode == IM_RGB) { this->file_color_mode |= IM_PACKED; bpp = 24; if (imColorModeHasAlpha(this->user_color_mode)) { this->file_color_mode |= IM_ALPHA; bpp = 32; this->rmask = 0x00FF0000; this->roff = 16; this->gmask = 0x0000FF00; this->goff = 8; this->bmask = 0x000000FF; this->boff = 0; } } else bpp = 8; this->line_buffer_extra = 4; // room enough for padding imAttribTable* attrib_table = AttribTable(); const void* attrib_data = attrib_table->Get("FPS"); if (attrib_data) fps = *(float*)attrib_data; else fps = 15; if (this->compression[0] == 0 || imStrEqual(this->compression, "NONE")) this->use_compressor = 0; else this->use_compressor = 1; dib = imDibCreate(width, height, bpp); if (use_compressor) { memset(&compvars, 0, sizeof(COMPVARS)); compvars.cbSize = sizeof(COMPVARS); if (imStrEqual(this->compression, "CUSTOM")) { if (ICCompressorChoose(NULL, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, dib->dib, NULL, &compvars, "Choose Compression") == FALSE) return IM_ERR_COMPRESS; } else { compvars.dwFlags = ICMF_COMPVARS_VALID; compvars.fccType = ICTYPE_VIDEO; int* attrib = (int*)attrib_table->Get("KeyFrameRate"); if (attrib) compvars.lKey = *attrib; else compvars.lKey = 15; // same defaults of the dialog attrib = (int*)attrib_table->Get("DataRate"); if (attrib) compvars.lDataRate = *attrib / 8; else compvars.lDataRate = 300; // same defaults of the dialog attrib = (int*)attrib_table->Get("AVIQuality"); if (attrib) compvars.lQ = *attrib; else compvars.lQ = (DWORD)ICQUALITY_DEFAULT; if (imStrEqual(this->compression, "RLE")) compvars.fccHandler = mmioFOURCC('M','R','L','E'); else if (imStrEqual(this->compression, "CINEPACK")) compvars.fccHandler = mmioFOURCC('c','v','i','d'); else compvars.fccHandler = mmioFOURCC(compression[0],compression[1],compression[2],compression[3]); compvars.hic = ICOpen(ICTYPE_VIDEO, compvars.fccHandler, ICMODE_COMPRESS); } if (compvars.hic == NULL) use_compressor = 0; } AVISTREAMINFO streaminfo; memset(&streaminfo, 0, sizeof(AVISTREAMINFO)); streaminfo.fccType = streamtypeVIDEO; streaminfo.dwScale = 1000; streaminfo.dwRate = (DWORD)(fps*1000); SetRect(&streaminfo.rcFrame, 0, 0, width, height); if (use_compressor) { streaminfo.fccHandler = compvars.fccHandler; streaminfo.dwQuality = compvars.lQ; } else { streaminfo.fccHandler = mmioFOURCC('D','I','B',' '); streaminfo.dwQuality = (DWORD)ICQUALITY_DEFAULT; } /* creates a new stream in the new file */ HRESULT hr = AVIFileCreateStream(file, &stream, &streaminfo); if (hr != 0) return IM_ERR_ACCESS; /* set stream format */ if (use_compressor) { if (!ICSeqCompressFrameStart(&compvars, dib->bmi)) return IM_ERR_COMPRESS; hr = AVIStreamSetFormat(stream, 0, compvars.lpbiOut, dib->size - dib->bits_size); } else hr = AVIStreamSetFormat(stream, 0, dib->dib, dib->size - dib->bits_size); if (hr != 0) return IM_ERR_ACCESS; return IM_ERR_NONE; }
int imFileFormatAVI::ReadImageInfo(int index) { this->current_frame = index; if (this->frame) // frame reading already prepared return IM_ERR_NONE; /* get stream format */ LONG formsize; AVIStreamReadFormat(stream, 0, NULL, &formsize); BITMAPINFO *bmpinfo = (BITMAPINFO*)malloc(formsize); HRESULT hr = AVIStreamReadFormat(stream, 0, bmpinfo, &formsize); if (hr != 0) { free(bmpinfo); return IM_ERR_ACCESS; } int top_down = 0; if (bmpinfo->bmiHeader.biHeight < 0) top_down = 1; this->width = bmpinfo->bmiHeader.biWidth; this->height = top_down? -bmpinfo->bmiHeader.biHeight: bmpinfo->bmiHeader.biHeight; int bpp = bmpinfo->bmiHeader.biBitCount; imAttribTable* attrib_table = AttribTable(); attrib_table->Set("FPS", IM_FLOAT, 1, &fps); this->file_data_type = IM_BYTE; if (bpp > 8) { this->file_color_mode = IM_RGB; this->file_color_mode |= IM_PACKED; } else { this->palette_count = 1 << bpp; this->file_color_mode = IM_MAP; } if (bpp < 8) this->convert_bpp = bpp; if (bpp == 32) this->file_color_mode |= IM_ALPHA; if (top_down) this->file_color_mode |= IM_TOPDOWN; if (bpp <= 8) { /* updates the palette_count based on the number of colors used */ if (bmpinfo->bmiHeader.biClrUsed != 0 && (int)bmpinfo->bmiHeader.biClrUsed < this->palette_count) this->palette_count = bmpinfo->bmiHeader.biClrUsed; ReadPalette((unsigned char*)bmpinfo->bmiColors); } free(bmpinfo); this->line_buffer_extra = 4; // room enough for padding /* prepares to read data from the stream */ if (bpp == 32 || bpp == 16) { BITMAPINFOHEADER info; memset(&info, 0, sizeof(BITMAPINFOHEADER)); info.biSize = sizeof(BITMAPINFOHEADER); info.biWidth = width; info.biHeight = height; info.biPlanes = 1; info.biBitCount = (WORD)bpp; frame = AVIStreamGetFrameOpen(stream, &info); } else frame = AVIStreamGetFrameOpen(stream, NULL); if (!frame) return IM_ERR_ACCESS; return IM_ERR_NONE; }
int imFileFormatBMP::ReadImageInfo(int index) { (void)index; unsigned int dword; this->file_data_type = IM_BYTE; if (this->is_os2) { short word; /* reads the image width */ imBinFileRead(handle, &word, 1, 2); this->width = (int)word; /* reads the image height */ imBinFileRead(handle, &word, 1, 2); this->height = (int)((word < 0)? -word: word); dword = word; // it will be used later } else { /* reads the image width */ imBinFileRead(handle, &dword, 1, 4); this->width = (int)dword; /* reads the image height */ imBinFileRead(handle, &dword, 1, 4); this->height = (int)dword; if (this->height < 0) this->height = -this->height; } /* jump 2 bytes (planes) */ imBinFileSeekOffset(handle, 2); /* reads the number of bits per pixel */ imBinFileRead(handle, &this->bpp, 1, 2); if (imBinFileError(handle)) return IM_ERR_ACCESS; // sanity check if (this->bpp != 1 && this->bpp != 4 && this->bpp != 8 && this->bpp != 16 && this->bpp != 24 && this->bpp != 32) return IM_ERR_DATA; // another sanity check if (this->comp_type == BMP_BITFIELDS && this->bpp != 16 && this->bpp != 32) return IM_ERR_DATA; if (this->bpp > 8) { this->file_color_mode = IM_RGB; this->file_color_mode |= IM_PACKED; } else { this->palette_count = 1 << bpp; this->file_color_mode = IM_MAP; } if (this->bpp < 8) this->convert_bpp = this->bpp; if (this->bpp == 32) this->file_color_mode |= IM_ALPHA; if (dword < 0) this->file_color_mode |= IM_TOPDOWN; this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 4); this->line_buffer_extra = 4; // room enough for padding if (this->is_os2) { if (this->bpp < 24) return ReadPalette(); return IM_ERR_NONE; } /* we already read the compression information */ /* jump 8 bytes (compression, image size) */ imBinFileSeekOffset(handle, 8); /* read the x resolution */ imBinFileRead(handle, &dword, 1, 4); float xres = (float)dword / 100.0f; /* read the y resolution */ imBinFileRead(handle, &dword, 1, 4); float yres = (float)dword / 100.0f; if (xres && yres) { imAttribTable* attrib_table = AttribTable(); attrib_table->Set("XResolution", IM_FLOAT, 1, &xres); attrib_table->Set("YResolution", IM_FLOAT, 1, &yres); attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPC"); } if (this->bpp <= 8) { /* reads the number of colors used */ imBinFileRead(handle, &dword, 1, 4); /* updates the palette_count based on the number of colors used */ if (dword != 0 && dword < (unsigned int)this->palette_count) this->palette_count = dword; /* jump 4 bytes (important colors) */ imBinFileSeekOffset(handle, 4); } else { /* jump 8 bytes (used colors, important colors) */ imBinFileSeekOffset(handle, 8); } if (imBinFileError(handle)) return IM_ERR_ACCESS; if (this->bpp <= 8) return ReadPalette(); if (this->bpp == 16 || this->bpp == 32) { if (this->comp_type == BMP_BITFIELDS) { unsigned int Mask; unsigned int PalMask[3]; imBinFileRead(handle, PalMask, 3, 4); if (imBinFileError(handle)) return IM_ERR_ACCESS; this->roff = 0; this->rmask = Mask = PalMask[0]; while (!(Mask & 0x01) && (Mask != 0)) {Mask >>= 1; this->roff++;} this->goff = 0; this->gmask = Mask = PalMask[1]; while (!(Mask & 0x01) && (Mask != 0)) {Mask >>= 1; this->goff++;} this->boff = 0; this->bmask = Mask = PalMask[2]; while (!(Mask & 0x01) && (Mask != 0)) {Mask >>= 1; this->boff++;} } else { if (this->bpp == 16)
int imFileFormatECW::ReadImageData(void* data) { imAttribTable* attrib_table = AttribTable(); int i, *attrib_data, view_width, view_height, nBands = imColorModeDepth(this->file_color_mode); // this size is free, can be anything, but we restricted to less than the image size attrib_data = (int*)attrib_table->Get("ViewWidth"); view_width = attrib_data? *attrib_data: this->width; if (view_width > this->width) view_width = this->width; attrib_data = (int*)attrib_table->Get("ViewHeight"); view_height = attrib_data? *attrib_data: this->height; if (view_height > this->height) view_height = this->height; imCounterTotal(this->counter, view_height, "Reading ECW..."); { int xmin, xmax, ymin, ymax, band_start; // full image if not defined. // this size must be inside the image attrib_data = (int*)attrib_table->Get("ViewXmin"); xmin = attrib_data? *attrib_data: 0; if (xmin < 0) xmin = 0; attrib_data = (int*)attrib_table->Get("ViewYmin"); ymin = attrib_data? *attrib_data: 0; if (ymin < 0) ymin = 0; attrib_data = (int*)attrib_table->Get("ViewXmax"); xmax = attrib_data? *attrib_data: this->width-1; if (xmax > this->width-1) xmax = this->width-1; attrib_data = (int*)attrib_table->Get("ViewYmax"); ymax = attrib_data? *attrib_data: this->height-1; if (ymax > this->height-1) ymax = this->height-1; band_start = 0; UINT16* start_plane = (UINT16*)attrib_table->Get("MultiBandSelect"); if (start_plane) band_start = *start_plane; UINT32 *pBandList = (UINT32*)malloc(sizeof(UINT32)*nBands); for(i = 0; i < nBands; i++) pBandList[i] = i+band_start; NCSError eError = NCScbmSetFileView(this->pNCSFileView, nBands, pBandList, xmin, ymin, xmax, ymax, view_width, view_height); free(pBandList); if( eError != NCS_SUCCESS) return IM_ERR_DATA; } // this is necessary to fool line buffer management this->width = view_width; this->height = view_height; this->line_buffer_size = imImageLineSize(this->width, this->file_color_mode, this->file_data_type); NCSEcwCellType eType = NCSCT_UINT8; int type_size = 1; if (this->file_data_type == IM_SHORT) { eType = NCSCT_INT16; type_size = 2; } else if (this->file_data_type == IM_USHORT) { eType = NCSCT_UINT16; type_size = 2; } else if (this->file_data_type == IM_FLOAT) { eType = NCSCT_IEEE4; type_size = 4; } UINT8 **ppOutputLine = (UINT8**)malloc(sizeof(UINT8*)*nBands); UINT8 *ppOutputBuffer = (UINT8*)malloc(type_size*view_width*nBands); for(i = 0; i < nBands; i++) ppOutputLine[i] = ppOutputBuffer + i*type_size*view_width; for (int row = 0; row < view_height; row++) { NCSEcwReadStatus eError = NCScbmReadViewLineBILEx(this->pNCSFileView, eType, (void**)ppOutputLine); if( eError != NCS_SUCCESS) { free(ppOutputLine); free(ppOutputBuffer); return IM_ERR_DATA; } iCopyDataBuffer(ppOutputLine, (imbyte*)this->line_buffer, nBands, view_width, type_size); imFileLineBufferRead(this, data, row, 0); if (!imCounterInc(this->counter)) { free(ppOutputLine); free(ppOutputBuffer); return IM_ERR_COUNTER; } } free(ppOutputLine); free(ppOutputBuffer); return IM_ERR_NONE; }
int imFileFormatECW::ReadImageInfo(int index) { NCSFileViewFileInfoEx *pNCSFileInfo; imAttribTable* attrib_table = AttribTable(); (void)index; if (NCScbmGetViewFileInfoEx(this->pNCSFileView, &pNCSFileInfo) != NCS_SUCCESS) return IM_ERR_ACCESS; this->width = pNCSFileInfo->nSizeX; this->height = pNCSFileInfo->nSizeY; switch(pNCSFileInfo->eColorSpace) { case NCSCS_GREYSCALE: this->file_color_mode = IM_GRAY; break; case NCSCS_YUV: case NCSCS_sRGB: this->file_color_mode = IM_RGB; break; case NCSCS_YCbCr: this->file_color_mode = IM_YCBCR; break; case NCSCS_MULTIBAND: /* multiband data, we read only one band */ this->file_color_mode = IM_GRAY; attrib_table->Set("MultiBandCount", IM_USHORT, 1, (void*)&pNCSFileInfo->nBands); break; default: return IM_ERR_DATA; } switch(pNCSFileInfo->eCellType) { case NCSCT_INT8: case NCSCT_UINT8: this->file_data_type = IM_BYTE; break; case NCSCT_INT16: this->file_data_type = IM_SHORT; break; case NCSCT_UINT16: this->file_data_type = IM_USHORT; break; case NCSCT_INT64: case NCSCT_INT32: // Should be: this->file_data_type = IM_INT; // but 32bits ints are not supported by the NCScbmReadViewLineBILEx function this->file_data_type = IM_SHORT; break; case NCSCT_UINT64: case NCSCT_UINT32: // Should be: this->file_data_type = IM_INT; // but 32bits ints are not supported by the NCScbmReadViewLineBILEx function this->file_data_type = IM_USHORT; break; case NCSCT_IEEE4: case NCSCT_IEEE8: this->file_data_type = IM_FLOAT; break; default: return IM_ERR_DATA; } int prec = pNCSFileInfo->pBands->nBits; if (prec < 8) this->convert_bpp = -prec; // just expand to 0-255 if (prec == 1 && this->file_color_mode == IM_GRAY) this->file_color_mode = IM_BINARY; if (pNCSFileInfo->nBands > imColorModeDepth(this->file_color_mode)) this->file_color_mode |= IM_ALPHA; if (this->file_color_mode != IM_GRAY) this->file_color_mode |= IM_PACKED; this->file_color_mode |= IM_TOPDOWN; float float_value = (float)pNCSFileInfo->fOriginX; attrib_table->Set("OriginX", IM_FLOAT, 1, (void*)&float_value); float_value = (float)pNCSFileInfo->fOriginY; attrib_table->Set("OriginY", IM_FLOAT, 1, (void*)&float_value); float_value = (float)pNCSFileInfo->fCWRotationDegrees; attrib_table->Set("Rotation", IM_FLOAT, 1, (void*)&float_value); float_value = (float)pNCSFileInfo->fCellIncrementX; attrib_table->Set("CellIncrementX", IM_FLOAT, 1, (void*)&float_value); float_value = (float)pNCSFileInfo->fCellIncrementY; attrib_table->Set("CellIncrementY", IM_FLOAT, 1, (void*)&float_value); attrib_table->Set("Datum", IM_BYTE, strlen(pNCSFileInfo->szDatum)+1, pNCSFileInfo->szDatum); attrib_table->Set("Projection", IM_BYTE, strlen(pNCSFileInfo->szProjection)+1, pNCSFileInfo->szProjection); switch (pNCSFileInfo->eCellSizeUnits) { case ECW_CELL_UNITS_INVALID: attrib_table->Set("CellUnits", IM_BYTE, 8, "INVALID"); break; case ECW_CELL_UNITS_METERS: attrib_table->Set("CellUnits", IM_BYTE, 7, "METERS"); break; case ECW_CELL_UNITS_DEGREES: attrib_table->Set("CellUnits", IM_BYTE, 7, "DEGREES"); break; case ECW_CELL_UNITS_FEET: attrib_table->Set("CellUnits", IM_BYTE, 5, "FEET"); break; case ECW_CELL_UNITS_UNKNOWN: attrib_table->Set("CellUnits", IM_BYTE, 8, "UNKNOWN"); break; } float_value = (float)pNCSFileInfo->nCompressionRate; attrib_table->Set("CompressionRatio", IM_FLOAT, 1, (void*)&float_value); return IM_ERR_NONE; }