bool ImageSaveManager::WriteImageIconFile(const string &fileName,corona::Image *imgData,ImageSaveFiles &retFileNames) const { //Test if we save icons if(!saveIcon || iconSize == 0) { return false; } //Create a scaled version of the image corona::Image * iconImage =ScaleImage(iconSize,iconSize,imgData); //Save a icon version of the image if(iconImage) { string outName = fileName + "_icon." + iconExtension; //Write the file out if(!corona::SaveImage(outName.c_str(), corona::FF_AUTODETECT, iconImage)) { LOGERR(("ImageSaveManager::WriteImageIconFile - Unable to save image %s",outName.c_str())); delete iconImage; return false; } //Save the icon name retFileNames.iconName = outName; //Clean up delete iconImage; } return true; }
wxBitmap ScaleImageToBitmap(const wxImage& image, const wxWindow* context, const wxSize& output_size, const wxRect& usable_rect, LSIFlags flags, const wxColour& fill_color) { double scale_factor = context->GetContentScaleFactor(); return wxBitmap(ScaleImage(image, 1.0, scale_factor, output_size, usable_rect, flags, fill_color), wxBITMAP_SCREEN_DEPTH, scale_factor); }
wxBitmap ScaleImageToBitmap(const wxImage& image, const wxWindow* context, double source_scale, LSIFlags flags, const wxColour& fill_color) { double scale_factor = context->GetContentScaleFactor(); return wxBitmap(ScaleImage(image, source_scale, scale_factor, wxDefaultSize, wxDefaultSize, flags, fill_color), wxBITMAP_SCREEN_DEPTH, scale_factor); }
int ShowVideo(void) { Image *Output; int SX,SY; /* Must have active video image, X11 display */ if(!VideoImg||!VideoImg->Data) return(0); /* Allocate image buffer if none */ //if(!OutImg.Data&&!NewImage(&OutImg,XSize,YSize)) return(0); /* If not scaling or post-processing image, avoid extra work */ if(!(Effects&(EFF_SOFTEN|EFF_SCALE|EFF_TVLINES))) { FlipImage(VideoImg); return(1); } /* By default, we will be showing OutImg */ Output = &OutImg; SX = 0; SY = 0; if(Effects&EFF_SOFTEN) { /* Apply softening */ SoftenImage(&OutImg,VideoImg,VideoX,VideoY,VideoW,VideoH); /* Apply TV scanlines, if needed */ if(Effects&EFF_TVLINES) TelevizeImage(&OutImg,0,0,OutImg.W,OutImg.H); } else if(Effects&EFF_TVLINES) { if(Effects&EFF_SCALE) { /* Scale VideoImg into OutImg */ ScaleImage(&OutImg,VideoImg,VideoX,VideoY,VideoW,VideoH); /* Apply TV scanlines */ TelevizeImage(&OutImg,0,0,OutImg.W,OutImg.H); } else { /* Center VideoImg in OutImg */ IMGCopy(&OutImg,(OutImg.W-VideoW)>>1,(OutImg.H-VideoH)>>1,VideoImg,VideoX,VideoY,VideoW,VideoH,-1); /* Apply TV scanlines */ TelevizeImage(&OutImg,(OutImg.W-VideoW)>>1,(OutImg.H-VideoH)>>1,VideoW,VideoH); } } else if((OutImg.W==VideoW)&&(OutImg.H==VideoH))
void Tagimage::resizeImage(int _width, int _height) { /* Image *resized_image = ResizeImage(image, (int)((float)width/scale), (int)((float)height/scale), LanczosFilter, 1.0, &exception); */ Image *resized_image = ScaleImage(image, _width, _height, &exception); DestroyImage(image); image = resized_image; width = image->columns; height = image->rows; config->GRID_WIDTH = width; config->GRID_HEIGHT = height; if(config->DEBUG) cout << "tag resized to :" << width << ", " << height << endl; }
/*************************************************************** [NAME] SaveIteration [SYNOPSIS] void SaveIteration(Vector *MyVector, int iteration, char *filename) [DESCRIPTION] This function is used to save a series of images while iterating. The function saves an image with the specified outputname + a number indicating which iteration the picture represents. [USAGE] {\tt SaveIteration(TestVector, 123, "testImage");} Saves the vector {\tt TestVector} as the image `{\tt testimage.123.pet}'. [REVISION] Dec. 94, JJJ July 2006, Joern Schulz ***************************************************************/ void SaveIteration(Vector *MyVector, int iteration, char *filename) { char outfilename[100]; char itstr[10]; Image *NewImage; strcpy(outfilename,filename); sprintf(itstr,".%d",iteration); strcat(outfilename,itstr); NewImage=VectorToImage(MyVector,itINI.XSamples,itINI.YSamples); RenameImage(NewImage,outfilename); NewImage->DeltaX=itINI.DeltaX; NewImage->DeltaY=itINI.DeltaY; NewImage->Xmin=itINI.Xmin; NewImage->Ymin=itINI.Ymin; ScaleImage(NewImage); WritePET(NewImage); FreeImage(NewImage); }
static ERL_NIF_TERM exmagick_set_size (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { long width, height; Image* resized_image; exm_resource_t *resource; EXM_INIT; ErlNifResourceType *type = (ErlNifResourceType *) enif_priv_data(env); if (0 == enif_get_resource(env, argv[0], type, (void **) &resource)) { EXM_FAIL(ehandler, "invalid handle"); } if (resource->image == NULL) { EXM_FAIL(ehandler, "image not loaded"); } if (0 == enif_get_long(env, argv[1], &width)) { EXM_FAIL(ehandler, "width: bad argument"); } if (0 == enif_get_long(env, argv[2], &height)) { EXM_FAIL(ehandler, "height: bad argument"); } resized_image = ScaleImage(resource->image, width, height, &resource->e_info); if (resized_image == NULL) { CatchException(&resource->e_info); EXM_FAIL(ehandler, resource->e_info.reason); } DestroyImage(resource->image); resource->image = resized_image; return(enif_make_tuple2(env, enif_make_atom(env, "ok"), argv[0])); ehandler: return(enif_make_tuple2(env, enif_make_atom(env, "error"), exmagick_make_utf8str(env, errmsg))); }
void ezQtImageWidget::on_ButtonZoomOut_clicked() { ScaleImage(0.75f); }
void ezQtImageWidget::on_ButtonZoomIn_clicked() { ScaleImage(1.25f); }
void DisparityPlugin::Draw(double x, double y, double scale) { // Calculate the correct offsets and dimensions int x_offset = offset_x_; int y_offset = offset_y_; int width = width_; int height = height_; if (units_ == PERCENT) { x_offset = offset_x_ * canvas_->width() / 100.0; y_offset = offset_y_ * canvas_->height() / 100.0; width = width_ * canvas_->width() / 100.0; height = height_ * canvas_->height() / 100.0; } // Scale the source image if necessary if (width != last_width_ || height != last_height_) { ScaleImage(width, height); } // Calculate the correct render position int x_pos = 0; int y_pos = 0; if (anchor_ == TOP_LEFT) { x_pos = x_offset; y_pos = y_offset; } else if (anchor_ == TOP_CENTER) { x_pos = (canvas_->width() - width) / 2.0 + x_offset; y_pos = y_offset; } else if (anchor_ == TOP_RIGHT) { x_pos = canvas_->width() - width - x_offset; y_pos = y_offset; } else if (anchor_ == CENTER_LEFT) { x_pos = x_offset; y_pos = (canvas_->height() - height) / 2.0 + y_offset; } else if (anchor_ == CENTER) { x_pos = (canvas_->width() - width) / 2.0 + x_offset; y_pos = (canvas_->height() - height) / 2.0 + y_offset; } else if (anchor_ == CENTER_RIGHT) { x_pos = canvas_->width() - width - x_offset; y_pos = (canvas_->height() - height) / 2.0 + y_offset; } else if (anchor_ == BOTTOM_LEFT) { x_pos = x_offset; y_pos = canvas_->height() - height - y_offset; } else if (anchor_ == BOTTOM_CENTER) { x_pos = (canvas_->width() - width) / 2.0 + x_offset; y_pos = canvas_->height() - height - y_offset; } else if (anchor_ == BOTTOM_RIGHT) { x_pos = canvas_->width() - width - x_offset; y_pos = canvas_->height() - height - y_offset; } glPushMatrix(); glLoadIdentity(); glOrtho(0, canvas_->width(), canvas_->height(), 0, -0.5f, 0.5f); glRasterPos2f(x_pos, y_pos); DrawIplImage(&scaled_image_); glPopMatrix(); last_width_ = width; last_height_ = height; }
/*************************************************************** [NAME] main [SYNOPSIS] void main(int argc, char *argv[]) [DESCRIPTION] This is the main function which controls the program. [USAGE] {\tt it test.ini} Starts the main program with the parameteres specified in {\tt test.ini}. [REVISION] March 96, JJJ and PT\\ April 2, 96 PT (Moved last call to clock - error in SGI CC) July 2006, Modification of the complete routine for the R calling. ***************************************************************/ void it(double *InImage, double *OutImage, int *StartImageTrue, double *StartImage, char **mode, int *UseFast, char **RadonKernel, char **IterationsType, int *Iterations, int *SaveIterations, char **SaveIterationsName, double *LowestALevel, double *ConstrainMin, double *ConstrainMax, double *Alpha, double *Beta, double *Regularization, int *KernelFileSave, char **KernelFileName, char **RefFileName, int *ThetaSamples, double *ThetaMin, double *DeltaTheta, int *RhoSamples, double *RhoMin, double *DeltaRho, double *Xmin, double *Ymin, double *DeltaX, double *DeltaY, int *XSamples, int *YSamples, int *OverSamp, char **DebugLevel ) { int RealTid1,RealTid2,n; float Tid, tempsuma, tempsumb, mean; char Value[100]; Vector *xvector, *tempvector, *bvector; GetDateTime(Value,_RealTime); sscanf(Value,"%i",&RealTid1); Tid=clock(); if (strstr(*DebugLevel,"HardCore")) DebugNiveau=_DHardCore; else DebugNiveau=_DNormal; Print(_DNormal,"\n********************************************\n\n"); Print(_DNormal,"Iterative Reconstruction program version 2.0\n"); Print(_DNormal," Peter Toft and Jesper James Jensen\n"); Print(_DNormal," Implemented in R by Joern Schulz\n"); Print(_DNormal,"\n********************************************\n"); ReadItArgs("InputData", *mode, UseFast, *RadonKernel, *IterationsType, Iterations, SaveIterations, *SaveIterationsName, LowestALevel, ConstrainMin, ConstrainMax, Alpha, Beta, Regularization, KernelFileSave, *KernelFileName, *RefFileName, ThetaSamples, ThetaMin, DeltaTheta, RhoSamples, RhoMin, DeltaRho, Xmin, Ymin, DeltaX, DeltaY, XSamples, YSamples, OverSamp, *DebugLevel); // ================================================================== // Initialization of radon-image and the System-Matrix A if (itINI.IsFast) AMatrix=GenerateAMatrix(); bvector=DoubleToFloatVector(InImage, itINI.ThetaSamples, itINI.RhoSamples); // ================================================================== // Regularisation and initialisation of a Start-Image /* If regularisation is used, concatenate the bvector with zeroes */ if (itINI.Regularization>0) VectorCat(bvector,InitVector(AMatrix->M-bvector->N)); if (*StartImageTrue) { Print(_DDetail, "A StartImage was specified. \n"); xvector=DoubleToFloatVector(StartImage, itINI.XSamples, itINI.YSamples); } else { xvector=InitVector(itINI.XSamples*itINI.YSamples); if (itINI.IsFast) { /* The fast version, we can use the a-matrix */ tempsuma=0; tempsumb=0; tempvector=SumRowSparseMatrix(AMatrix); for(n=0; n<tempvector->N; n++) tempsuma+=tempvector->value[n]; for(n=0; n<bvector->N; n++) tempsumb+=bvector->value[n]; mean=tempsumb/tempsuma; for(n=0; n<xvector->N; n++) xvector->value[n]=mean; } else { /* we have to estimate the mean value */ tempsumb=0; for(n=0; n<bvector->N; n++) tempsumb+=bvector->value[n]; mean=tempsumb/(itINI.ThetaSamples*itINI.RhoSamples*itINI.XSamples*itINI.DeltaX); for(n=0; n<xvector->N; n++) xvector->value[n]=mean; } //Print(_DNormal,"Estimated mean of output image: %f \n",mean); Print(_DNormal,"Image-Initialization with: %f \n",mean); } // ================================================================== // Choice the corresponding Algorithm switch (itINI.Algorithm){ /* Main choice of algorithm */ case _CG: if (itINI.IsFast) MyImage=FAST_CG(AMatrix,xvector,bvector); else MyImage=SLOW_CG(xvector,bvector); break; case _EM: if (itINI.IsFast) MyImage=FAST_EM(AMatrix,xvector, bvector); else MyImage=SLOW_EM(xvector, bvector); break; case _ART: if (itINI.IsFast) MyImage=FAST_ART(AMatrix,xvector,bvector); else MyImage=SLOW_ART(xvector,bvector); break; } ScaleImage(MyImage); Print(_DDetail,"\n"); PrintStats(_DDetail, MyImage); // ================================================================== // Storage of reconstructed data and empty out the memory. ImageToFloat(OutImage, MyImage); FreeImage(MyImage); FreeVector(xvector); FreeVector(bvector); if (itINI.IsFast) FreeSparseMatrix(AMatrix); // ================================================================== // Calculation of the time-consuming. Tid=(clock()-Tid)/(float)CLOCKS_PER_SEC; GetDateTime(Value,_RealTime); sscanf(Value,"%i",&RealTid2); Print(_DNormal,"IT: Program was active for %.2f seconds\n",Tid) ; Print(_DNormal," World time elapsed %d seconds\n", (RealTid2-RealTid1)); Print(_DNormal," Program used %.2f %% cpu time\n", Tid/((float)RealTid2-RealTid1)*100); Print(_DNormal,"\n"); }
corona::Image * ImageSaveManager::CreateTileCubeMapImage(uint maxWidth, uint maxHeight, corona::Image * images[6]) const { //Check max width and height if(maxWidth == 0 || maxHeight == 0) { LOGERR(("ImageSaveManager::CreateTileCubeMapImage - Zero width and height")); return NULL; } //Offset arrays for image positioning uint XOffsetArray[6] = {2,0,1,1,1,3}; uint YOffsetArray[6] = {1,1,0,2,1,1}; //Flip the positioning of the "Y" pieces on X axis flip if(flipXAxis) { YOffsetArray[2] = 2; YOffsetArray[3] = 0; } //Create a new blank image corona::Image * retImage = corona::CreateImage(maxWidth * 4,maxHeight * 3, corona::PF_R8G8B8A8); //Clear the starting buffer with white memset(retImage->getPixels(), 0xFF, retImage->getWidth() * retImage->getHeight() * 4); //Loop for all images for(uint i=0;i<6;i++) { //If there is a valid image if(images[i]) { corona::Image * tmpImage = images[i]; //If the dimensions do not equal the requested image size, // create a new image if((uint)images[i]->getWidth() != maxWidth || (uint)images[i]->getHeight() != maxHeight) { tmpImage = ScaleImage(maxWidth,maxHeight,images[i]); if(!tmpImage) { LOGERR(("ImageSaveManager::CreateTileCubeMapImage -Unable to scale image")); return retImage; } } //Get a pointer to the source and destination pixels udword * srcImg = (udword *)tmpImage->getPixels(); udword * destImg = (udword *)retImage->getPixels() + ((YOffsetArray[i]*maxHeight) * maxWidth*4) + ((XOffsetArray[i]*maxWidth)); //Loop and copy the image data for(uint h=0;h<maxHeight;h++) { //Copy a single line memcpy(destImg, srcImg, maxWidth*4); //Increment the pointers destImg += maxWidth*4; srcImg += maxWidth; } //Delete the temporary image if one was assigned if(tmpImage != images[i]) { delete tmpImage; } } } return retImage; }
static wxImage LoadScaledImage(const std::string& file_path, const wxWindow* context, const wxSize& output_size, const wxRect& usable_rect, LSIFlags flags, const wxColour& fill_color) { std::string fpath, fname, fext; SplitPath(file_path, &fpath, &fname, &fext); const double window_scale_factor = context->GetContentScaleFactor(); // Compute the total scale factor from the ratio of DIPs to window pixels (FromDIP) and // window pixels to framebuffer pixels (GetContentScaleFactor). // NOTE: Usually only one of these is meaningful: // - On Windows/GTK2: content_scale = 1.0, FromDIP = 96DPI -> Screen DPI // - On Mac OS X: content_scale = screen_dpi / 96, FromDIP = 96DPI -> 96DPI (no-op) // [The 1024 is arbitrarily large to minimise rounding error, it has no significance] const double scale_factor = (context->FromDIP(1024) / 1024.0) * window_scale_factor; // We search for files on quarter ratios of DIPs to framebuffer pixels. // By default, the algorithm prefers to find an exact or bigger size then downscale if // needed but will resort to upscaling if a bigger image cannot be found. // E.g. A basic retina screen on Mac OS X has a scale_factor of 2.0, so we would look for // @2x, @2.25x, @2.5x, @2.75x, @3x, @1.75x, @1.5x, @1.25x, @1x, then give up. // (At 125% on Windows the search is @1.25, @1.5, @1.75, @2, @2.25, @1) // If flags does not include LSI_SCALE_DOWN (i.e. we would be forced to crop big // images instead of scaling them) then we will only accept smaller sizes, i.e. // @2x, @1.75, @1.5, @1.25, @1, then give up. // NOTE: We do a lot of exact comparisons against floating point here but it's fine // because the numbers involved are all powers of 2 so can be represented exactly. wxImage image; double selected_image_scale = 1; { auto image_check = [&](double scale) -> bool { std::string path = fpath + fname + StringFromFormat("@%gx", scale) + fext; if (!File::Exists(path)) { // Special Case: @1x may not have a suffix at all. if (scale != 1.0 || !File::Exists(file_path)) return false; path = file_path; } if (!image.LoadFile(StrToWxStr(path), wxBITMAP_TYPE_ANY)) return false; selected_image_scale = scale; return true; }; const bool prefer_smaller = !(flags & LSI_SCALE_DOWN); const double scale_factor_quarter = prefer_smaller ? std::floor(scale_factor * 4) / 4 : std::ceil(scale_factor * 4) / 4; // Search for bigger sizes first (preferred) if (!prefer_smaller) { // We search within a 'circle' of the exact match limited by scale=1.0. // i.e. scale_factor = 1.5, radius = 0.5; scale = 2.5, radius = 1.5. // The minimum radius is 1.0. double limit = std::max(scale_factor_quarter * 2 - 1, scale_factor_quarter + 1); for (double quarter = scale_factor_quarter; quarter <= limit; quarter += 0.25) { if (image_check(quarter)) break; } } // If we didn't hit a bigger size then we'll fallback to looking for smaller ones if (!image.IsOk()) { double quarter = scale_factor_quarter; if (!prefer_smaller) // So we don't recheck the exact match quarter -= 0.25; for (; quarter >= 1.0; quarter -= 0.25) { if (image_check(quarter)) break; } } } // The file apparently does not exist so we give up. Create a white square placeholder instead. if (!image.IsOk()) { wxLogError("Could not find resource: %s", StrToWxStr(file_path)); image.Create(1, 1, false); image.Clear(0xFF); } return ScaleImage(image, selected_image_scale, window_scale_factor, output_size, usable_rect, flags, fill_color); }
int ShowVideo(void) { Image *Output; int SX,SY; /* Must have active video image, X11 display */ if(!VideoImg||!VideoImg->Data) return(0); /* Allocate image buffer if none */ if(!OutImg.Data&&!NewImage(&OutImg,XSize,YSize)) return(0); /* Count framerate */ if((Effects&EFF_SHOWFPS)&&(++FrameCount>=120)) { struct timeval NewTS; int Time; gettimeofday(&NewTS,0); Time = (NewTS.tv_sec-TimeStamp.tv_sec)*1000 + (NewTS.tv_usec-TimeStamp.tv_usec)/1000; FrameRate = 1000*FrameCount/(Time>0? Time:1); TimeStamp = NewTS; FrameCount = 0; FrameRate = FrameRate>999? 999:FrameRate; } /* If not scaling or post-processing image, avoid extra work */ if(!(Effects&(EFF_SOFTEN|EFF_SCALE|EFF_TVLINES))) { /* Show framerate if requested */ if((Effects&EFF_SHOWFPS)&&(FrameRate>0)) { char S[8]; sprintf(S,"%02dfps",FrameRate); PrintXY(VideoImg,S, 8,8, FPS_COLOR,PIXEL(255,255,255) ); } screen_buffer_t screen_buf[1]; screen_get_window_property_pv(window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)screen_buf); int bg[] = { SCREEN_BLIT_END }; screen_blit(ctxt, screen_buf[0], VideoImg->pbuf, bg); screen_post_window(window, screen_buf[0], 1, rect, 0); return 1; } /* By default, we will be showing OutImg */ Output = &OutImg; SX = 0; SY = 0; if(Effects&EFF_SOFTEN) { /* Apply softening */ SoftenImage(&OutImg,VideoImg,VideoX,VideoY,VideoW,VideoH); /* Apply TV scanlines, if needed */ if(Effects&EFF_TVLINES) TelevizeImage(&OutImg,0,0,OutImg.W,OutImg.H); } else if(Effects&EFF_TVLINES) { if(Effects&EFF_SCALE) { /* Scale VideoImg into OutImg */ ScaleImage(&OutImg,VideoImg,VideoX,VideoY,VideoW,VideoH); /* Apply TV scanlines */ TelevizeImage(&OutImg,0,0,OutImg.W,OutImg.H); } else { /* Center VideoImg in OutImg */ IMGCopy(&OutImg,(OutImg.W-VideoW)>>1,(OutImg.H-VideoH)>>1,VideoImg,VideoX,VideoY,VideoW,VideoH,-1); /* Apply TV scanlines */ TelevizeImage(&OutImg,(OutImg.W-VideoW)>>1,(OutImg.H-VideoH)>>1,VideoW,VideoH); } } else if((OutImg.W==VideoW)&&(OutImg.H==VideoH))
static void CompressTextureSet( Vector<VirtFS::VirtDesc>& files, Pair<CString, ImageProcessor> const& file, FileProcessor* cooker, TerminalCursor& cursor) { Resource r(MkUrl(file.first.c_str())); auto outName = Path(file.first).removeExt(); PixCmp cmp = PixCmp::RGBA; BitFmt bfmt; Bytes data; Size size; auto decoder = image_decoders.find(file.second); if(decoder == image_decoders.end()) return; if(!decoder->second(cooker, file, cmp, bfmt, size, data, r)) return; if(size.area() == 0) { return; } texture_settings_t settings; settings.flags = stb::ImageHint::Undefined; settings.max_size = max_texture_size; settings.min_size = min_texture_size; settings.channels = 4; settings.formats = Compress_ALL; /*!< Use all formats by default */ settings.parse(outName); if(size.w < settings.max_size && size.h < settings.max_size) { std::tie(data, size) = ScaleImage( std::move(data), size, settings.max_size, settings.flags); } else if(size.w > settings.max_size && size.h > settings.max_size) { std::tie(data, size) = ScaleImage( std::move(data), size, settings.max_size, settings.flags); } common_tools_t tools = {cooker, cursor, settings, files}; if(settings.formats & Compress_DXT) CompressDXT(tools, file, size, data, outName); #if defined(HAVE_ETC2COMP) if(settings.formats & Compress_ETC) CompressETC12(tools, size, data, outName); #endif if(settings.formats & Compress_RAW) { /* Just export the raw image as RGBA8 */ IMG::serial_image img; img.size = size; img.v2.bit_fmt = BitFmt::UByte; img.v2.format.base_fmt = PixFmt::RGBA8; img.v2.format.c_flags = CompFlags::CompressionNone; img.v2.format.p_flags = PixFlg::None; auto rawName = outName.addExtension("raw"); files.emplace_back(rawName, Bytes(), 0); auto& rawData = files.back().data; rawData = Bytes::Alloc(sizeof(img) + data.size); MemCpy(Bytes::From(img), rawData.at(0, sizeof(img))); MemCpy(data, rawData.at(sizeof(img))); cursor.progress( TEXCOMPRESS_API "Exporting raw RGBA for {0}", file.first); } }
Image* generate_rendition(Image *const image, ImageInfo const*image_info, char const* spec, char const* rendition_path, ExceptionInfo *exception) { unsigned long crop_x; unsigned long crop_y; unsigned long crop_width; unsigned long crop_height; unsigned long width; unsigned long height; unsigned int quality; unsigned int resize; double blur; unsigned int is_progressive; Image const* cropped; Image *resized; RectangleInfo geometry; FilterTypes filter; ImageInfo *rendition_info; if (sscanf(spec, "%lux%lu+%lu+%lu+%lux%lu+%u+%lf+%u+%u", &crop_width, &crop_height, &crop_x, &crop_y, &width, &height, &resize, &blur, &quality, &is_progressive)) { if (width > 0 && height > 0) { if (crop_width > 0 && crop_height > 0) { geometry.x = crop_x; geometry.y = crop_y; geometry.width = crop_width; geometry.height = crop_height; cropped = CropImage(image, &geometry, exception); if (!cropped) { CatchException(exception); return NULL; } } else { cropped = image; } filter = get_filter(resize); switch (resize) { case Sample: resized = SampleImage(cropped, width, height, exception); break; case Scale: resized = ScaleImage(cropped, width, height, exception); break; case Thumbnail: resized = ThumbnailImage(cropped, width, height, exception); break; case Point: case Box: case Triangle: case Hermite: case Hanning: case Hamming: case Blackman: case Gaussian: case Quadratic: case Cubic: case Catrom: case Mitchell: case Lanczos: case Bessel: case Sinc: resized = ResizeImage(cropped, width, height, filter, blur, exception); break; } if (!resized) { CatchException(exception); return NULL; } rendition_info = CloneImageInfo(image_info); rendition_info->quality = quality; strncpy(resized->filename, rendition_path, MaxTextExtent); if (is_progressive) { rendition_info->interlace = LineInterlace; printf("progressive: %s\n", rendition_path); } if (!WriteImage(rendition_info, resized)) { CatchException(exception); DestroyImageInfo(rendition_info); return NULL; } printf("wrote %s\n", resized->filename); DestroyImageInfo(rendition_info); return resized; } } return NULL; }