struct R_image * image_clone_imlib2(Drawable drawable, struct R_image *image, int w, int h) { struct R_image *newimage; Imlib_Image img, newimg; int imagew, imageh; int neww, newh; if (image == NULL) { return NULL; } newimage = NULL; img = image->im2img; if (img) { imlib_context_set_drawable(drawable); imlib_context_set_image(img); imagew = imlib_image_get_width(); imageh = imlib_image_get_height(); if (w == 0) { neww = imagew; } else { neww = w; } if (h == 0) { newh = imageh; } else { newh = h; } newimg = imlib_create_cropped_scaled_image(0, 0, imagew, imageh, neww, newh); if (newimg == NULL) { return NULL; } newimage = image_alloc(); if (newimage == NULL) { return NULL; } newimage->w = neww; newimage->h = newh; newimage->im2img = newimg; } return newimage; }
IMAGE* load_png(int fd) { png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_uint_32 width, height; int bit_depth, color_type, interlace_type; png_bytep * row_pointers; int ckey = -1; png_color_16 *transv; IMAGE* image = NULL; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); if (png_ptr == NULL) goto err; info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) goto err; if ( setjmp(png_ptr->jmpbuf)) goto err; /* Set up the input control */ png_set_read_fn(png_ptr, (void*)fd, png_read_data); /* Read PNG header info */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); /* tell libpng to strip 16 bit/color files down to 8 bits/color */ png_set_strip_16(png_ptr) ; /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ png_set_packing(png_ptr); /* scale greyscale values to the range 0..255 */ if(color_type == PNG_COLOR_TYPE_GRAY) png_set_expand(png_ptr); /* For images with a single "transparent colour", set colour key; if more than one index has transparency, or if partially transparent entries exist, use full alpha channel */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { int num_trans; unsigned char *trans; png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &transv); if(color_type == PNG_COLOR_TYPE_PALETTE) { /* Check if all tRNS entries are opaque except one */ int i, t = -1; for(i = 0; i < num_trans; i++) if(trans[i] == 0) { if(t >= 0) break; t = i; } else if(trans[i] != 255) break; if(i == num_trans) { /* exactly one transparent index */ ckey = t; } else { /* more than one transparent index, or translucency */ png_set_expand(png_ptr); } } else ckey = 0; /* actual value will be set later */ } if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) png_set_gray_to_rgb(png_ptr); png_read_update_info(png_ptr, info_ptr); // png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, // &color_type, &interlace_type, NULL, NULL); image = image_alloc(width,height,bit_depth*info_ptr->channels); row_pointers = (png_bytep*) alloca(sizeof(png_bytep)*height); char* p = image->pixels; int pitch = (width*bit_depth*info_ptr->channels+7)/8; int i; for (i = 0; i < height; i++) { row_pointers[i] = p; p+=pitch; } /* Read the entire image in one go */ png_read_image(png_ptr, row_pointers); if (info_ptr->num_palette > 0) { COLOR *palette = image->palette; image->n_palette = info_ptr->num_palette; for(i=0; i<info_ptr->num_palette; i++) { palette[i].b = info_ptr->palette[i].blue; palette[i].g = info_ptr->palette[i].red; palette[i].r = info_ptr->palette[i].green; } } err: png_destroy_read_struct(&png_ptr, info_ptr ? &info_ptr : (png_infopp)0, (png_infopp)0); return image; }
IMAGE* load_bmp_buffer(unsigned char *buff) { int offset=0; WORD bfType; struct { DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } bf; RGBQUAD rgbquad[256]; BITMAPINFOHEADER bi; //fread(&bfType,1,sizeof(bfType),fd); memcpy(&bfType,buff+offset,sizeof(bfType)); offset+=sizeof(bfType); if (bfType != 'M'*256+'B') return NULL; //fread(&bf,1,sizeof(bf),fd); memcpy(&bf,buff+offset,sizeof(bf)); offset+=sizeof(bf); //fread(&bi,1,sizeof(bi),fd); memcpy(&bi,buff+offset,sizeof(bi)); offset+=sizeof(bi); if (bi.biCompression!=0 || bi.biWidth > 480 || bi.biHeight >272) return NULL; IMAGE *image = image_alloc(bi.biWidth,bi.biHeight,bi.biBitCount); int pitch = ((bi.biWidth * bi.biBitCount + 31)/8)&-4; //char *buffer = malloc(bi.biSizeImage); //image->pixels = buffer; char *buffer = image->pixels; if (bi.biBitCount<=8) { int ncolor = bi.biClrUsed; if (ncolor==0) ncolor = 1<< bi.biBitCount; //fread(rgbquad,1,sizeof(RGBQUAD)*ncolor,fd); memcpy(rgbquad,buff+offset,sizeof(RGBQUAD)*ncolor); offset+=sizeof(RGBQUAD)*ncolor; int i; for(i=0;i<ncolor;i++) { image->palette[i].r = rgbquad[i].rgbRed; image->palette[i].g = rgbquad[i].rgbGreen; image->palette[i].b = rgbquad[i].rgbBlue; } } //fseek(fd,bf.bfOffBits,SEEK_SET); offset=bf.bfOffBits; int x,y; switch(bi.biBitCount) { case 8: for(y=bi.biHeight-1;y>=0;y--) { //fread(buffer + pitch*y,1, pitch,fd); memcpy(buffer + pitch*y,buff+offset,pitch); offset+=pitch; } break; case 24: for(y=bi.biHeight-1;y>=0;y--) { //fread(buffer + pitch*y,1, pitch,fd); memcpy(buffer + pitch*y,buff+offset,pitch); offset+=pitch; char *p = buffer + pitch*y; for(x=0;x<bi.biWidth;x++) { int t = p[0]; p[0] = p[2]; p[2] = t; p+=3; } } } return image; }
int main(int argc, char* argv[]) { struct wave* w; struct image* img; int width, height; char* in_file_name; char* out_file_name; FILE* file; int style = DEFAULT_STYLE; /* Options */ int c; opterr = 0; print_greeting(); /* Defaults */ width = 1024; height = 256; in_file_name = ""; out_file_name = ""; while ((c = getopt (argc, argv, "W:H:hi:o:s:")) != -1) switch (c) { case 'W': width = atoi(optarg); DPRINTF("Width set to %d\n", width); break; case 'H': height = atoi(optarg); DPRINTF("Height set to %d\n", height); break; case 'h': print_help(); return 0; break; case 'i': in_file_name = optarg; break; case 'o': out_file_name = optarg; break; case 's': style = MIN(MAX(atoi(optarg), 1), MAX_STYLE); printf("Style set to %d\n", style); break; case '?': fprintf (stderr, "Unknown option `-%c'.\n", optopt); return 1; default: abort(); } if (argc == 1) { print_help(); return 0; } w = ini_wave(in_file_name); assert(w!=NULL); DPRINTF(PRINT_DIVISION); DPRINTF("We seem to have a valid WAVE file!\n"); /* Create image. Note width first.*/ img = image_alloc(width, height); draw_waveform(w, img, style); /* Output where? */ if (strlen(out_file_name) == 0) { asprintf(&out_file_name, "%s.png", in_file_name); /* Small leak; avoiding it would be a bit messy. */ } /* Open */ printf("Writing to file %s\n", out_file_name); file = fopen(out_file_name, "w"); assert(file != NULL); /* Write */ write_PNG_image_to_file(file, img); /* Close */ image_free(img); fclose(file); cleanup_wave(w); free(w); return 0; }
int image_gif_load(image *im) { int x, y, ofs; GifRecordType RecordType; GifPixelType *line = NULL; int ExtFunction = 0; GifByteType *ExtData; SavedImage *sp; SavedImage temp_save; int BackGround = 0; int trans_index = 0; // transparent index if any ColorMapObject *ColorMap; GifColorType *ColorMapEntry; temp_save.ExtensionBlocks = NULL; temp_save.ExtensionBlockCount = 0; // If reusing the object a second time, start over if (im->used) { DEBUG_TRACE("Recreating giflib objects\n"); image_gif_finish(im); if (im->fh != NULL) { // reset file to begining of image PerlIO_seek(im->fh, im->image_offset, SEEK_SET); } else { // reset SV read im->sv_offset = im->image_offset; } buffer_clear(im->buf); image_gif_read_header(im); } do { if (DGifGetRecordType(im->gif, &RecordType) == GIF_ERROR) { warn("Image::Scale unable to read GIF file (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(im->gif) == GIF_ERROR) { warn("Image::Scale unable to read GIF file (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } sp = &im->gif->SavedImages[im->gif->ImageCount - 1]; im->width = sp->ImageDesc.Width; im->height = sp->ImageDesc.Height; BackGround = im->gif->SBackGroundColor; // XXX needed? ColorMap = im->gif->Image.ColorMap ? im->gif->Image.ColorMap : im->gif->SColorMap; if (ColorMap == NULL) { warn("Image::Scale GIF image has no colormap (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } // Allocate storage for decompressed image image_alloc(im, im->width, im->height); New(0, line, im->width, GifPixelType); if (im->gif->Image.Interlace) { int i; for (i = 0; i < 4; i++) { for (x = InterlacedOffset[i]; x < im->height; x += InterlacedJumps[i]) { ofs = x * im->width; if (DGifGetLine(im->gif, line, 0) != GIF_OK) { warn("Image::Scale unable to read GIF file (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } for (y = 0; y < im->width; y++) { ColorMapEntry = &ColorMap->Colors[line[y]]; im->pixbuf[ofs++] = COL_FULL( ColorMapEntry->Red, ColorMapEntry->Green, ColorMapEntry->Blue, trans_index == line[y] ? 0 : 255 ); } } } } else { ofs = 0; for (x = 0; x < im->height; x++) { if (DGifGetLine(im->gif, line, 0) != GIF_OK) { warn("Image::Scale unable to read GIF file (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } for (y = 0; y < im->width; y++) { ColorMapEntry = &ColorMap->Colors[line[y]]; im->pixbuf[ofs++] = COL_FULL( ColorMapEntry->Red, ColorMapEntry->Green, ColorMapEntry->Blue, trans_index == line[y] ? 0 : 255 ); } } } Safefree(line); break; case EXTENSION_RECORD_TYPE: if (DGifGetExtension(im->gif, &ExtFunction, &ExtData) == GIF_ERROR) { warn("Image::Scale unable to read GIF file (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } if (ExtFunction == 0xF9) { // transparency info if (ExtData[1] & 1) trans_index = ExtData[4]; else trans_index = -1; im->has_alpha = 1; DEBUG_TRACE("GIF transparency index: %d\n", trans_index); } while (ExtData != NULL) { /* Create an extension block with our data */ #ifdef GIFLIB_API_50 if (GifAddExtensionBlock(&im->gif->ExtensionBlockCount, &im->gif->ExtensionBlocks, ExtFunction, ExtData[0], &ExtData[1]) == GIF_ERROR) { #else temp_save.Function = ExtFunction; if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1]) == GIF_ERROR) { #endif #ifdef GIFLIB_API_41 PrintGifError(); #endif warn("Image::Scale unable to read GIF file (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } if (DGifGetExtensionNext(im->gif, &ExtData) == GIF_ERROR) { #ifdef GIFLIB_API_41 PrintGifError(); #endif warn("Image::Scale unable to read GIF file (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } ExtFunction = 0; // CONTINUE_EXT_FUNC_CODE } break; case TERMINATE_RECORD_TYPE: default: break; } } while (RecordType != TERMINATE_RECORD_TYPE); return 1; } void image_gif_finish(image *im) { if (im->gif != NULL) { #ifdef GIFLIB_API_51 if (DGifCloseFile(im->gif, NULL) != GIF_OK) { #else if (DGifCloseFile(im->gif) != GIF_OK) { #endif #ifdef GIFLIB_API_41 PrintGifError(); #endif warn("Image::Scale unable to close GIF file (%s)\n", SvPVX(im->path)); } im->gif = NULL; DEBUG_TRACE("image_gif_finish\n"); } }
/* sampling. */ image *image_border(image *src) { image *dst = 0; const int d = 1; if ((src) && (dst = image_alloc(6, src[0].w + 2 * d, src[0].w + 2 * d, src[0].c ))) { const int n = src[0].w; const int c = src[0].c; const int b = 4; const int N = n + 2 * d; /* Copy all page data. */ blit(dst[0].p, N, d, d, src[0].p, n, 0, 0, n, n, c, b); blit(dst[1].p, N, d, d, src[1].p, n, 0, 0, n, n, c, b); blit(dst[2].p, N, d, d, src[2].p, n, 0, 0, n, n, c, b); blit(dst[3].p, N, d, d, src[3].p, n, 0, 0, n, n, c, b); blit(dst[4].p, N, d, d, src[4].p, n, 0, 0, n, n, c, b); blit(dst[5].p, N, d, d, src[5].p, n, 0, 0, n, n, c, b); border(dst + 0, rotN, dst + 5, rotN, d); border(dst + 5, rotN, dst + 1, rotN, d); border(dst + 1, rotN, dst + 4, rotN, d); border(dst + 4, rotN, dst + 0, rotN, d); border(dst + 1, rotR, dst + 2, rotN, d); border(dst + 1, rotL, dst + 3, rotN, d); border(dst + 2, rotN, dst + 0, rotL, d); border(dst + 3, rotN, dst + 0, rotR, d); border(dst + 2, rotL, dst + 4, rotL, d); border(dst + 2, rotR, dst + 5, rotL, d); border(dst + 3, rotL, dst + 5, rotR, d); border(dst + 3, rotR, dst + 4, rotR, d); #if 0 /* Corner patch hack. */ for (f = 0; f < 6; f++) for (k = 0; k < c; k++) { SAMP(dst[f], 0, 0, k) = (SAMP(dst[f], 1, 0, k) + SAMP(dst[f], 0, 1, k) + SAMP(dst[f], 1, 1, k)) / 3.0f; SAMP(dst[f], 0, M, k) = (SAMP(dst[f], 1, M, k) + SAMP(dst[f], 0, L, k) + SAMP(dst[f], 1, L, k)) / 3.0f; SAMP(dst[f], M, 0, k) = (SAMP(dst[f], L, 0, k) + SAMP(dst[f], M, 1, k) + SAMP(dst[f], L, 1, k)) / 3.0f; SAMP(dst[f], M, M, k) = (SAMP(dst[f], L, M, k) + SAMP(dst[f], M, L, k) + SAMP(dst[f], L, L, k)) / 3.0f; } #endif } return dst; }
int jpeg_read(image *im,const char *filename,int argc,char *argv[]) //GLOBAL(int) read_JPEG_file (char * filename) { /* This struct contains the JPEG decompression parameters and pointers to * working space (which is allocated as needed by the JPEG library). */ struct jpeg_decompress_struct cinfo; /* We use our private extension JPEG error handler. * Note that this struct must live as long as the main JPEG parameter * struct, to avoid dangling-pointer problems. */ struct my_error_mgr jerr; /* More stuff */ FILE * infile; /* source file */ // JSAMPARRAY buffer; /* Output row buffer */ //int row_stride; /* physical row width in output buffer */ int fmt; int ret=0; /* In this example we want to open the input file before doing anything else, * so that the setjmp() error recovery below can assume the file is open. * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that * requires it in order to read binary files. */ if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); return(IME_NOFILE); } /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; /* Establish the setjmp return context for my_error_exit to use. */ if (setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jpeg_destroy_decompress(&cinfo); fclose(infile); return IME_BADFILE; } /* Now we can initialize the JPEG decompression object. */ jpeg_create_decompress(&cinfo); /* Step 2: specify data source (eg, a file) */ jpeg_stdio_src(&cinfo, infile); /* Step 3: read file parameters with jpeg_read_header() */ (void) jpeg_read_header(&cinfo, TRUE); /* We can ignore the return value from jpeg_read_header since * (a) suspension is not possible with the stdio data source, and * (b) we passed TRUE to reject a tables-only JPEG file as an error. * See libjpeg.doc for more info. */ /* Step 4: set parameters for decompression */ /* In this example, we don't need to change any of the defaults set by * jpeg_read_header(), so we do nothing here. */ /* Step 5: Start decompressor */ (void) jpeg_start_decompress(&cinfo); /* We can ignore the return value since suspension is not possible * with the stdio data source. */ /* We may need to do some setup of our own at this point before reading * the data. After jpeg_start_decompress() we have the correct scaled * output image dimensions available, as well as the output colormap * if we asked for color quantization. * In this example, we need to make an output work buffer of the right size. */ /* JSAMPLEs per row in output buffer */ fmt = IM_RGB; if (cinfo.output_components == 1) fmt = IM_GRAY; ret = image_alloc(im,fmt,cinfo.output_width,cinfo.output_height); // row_stride = cinfo.output_width * cinfo.output_components; /* Make a one-row-high sample array that will go away when done with image */ // buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); /* Step 6: while (scan lines remain to be read) */ /* jpeg_read_scanlines(...); */ /* Here we use the library's state variable cinfo.output_scanline as the * loop counter, so that we don't have to keep track ourselves. */ while (cinfo.output_scanline < cinfo.output_height) { /* jpeg_read_scanlines expects an array of pointers to scanlines. * Here the array is only one element long, but you could ask for * more than one scanline at a time if that's more convenient. */ JSAMPROW buffer[1]; int flip = TRUE; // flip the image if (flip) buffer[0] = IROW(im,cinfo.output_height-1-cinfo.output_scanline); else buffer[0] = IROW(im,cinfo.output_scanline); (void) jpeg_read_scanlines(&cinfo, buffer, 1); } /* Step 7: Finish decompression */ (void) jpeg_finish_decompress(&cinfo); /* We can ignore the return value since suspension is not possible * with the stdio data source. */ /* Step 8: Release JPEG decompression object */ /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_decompress(&cinfo); /* After finish_decompress, we can close the input file. * Here we postpone it until after no more JPEG errors are possible, * so as to simplify the setjmp error logic above. (Actually, I don't * think that jpeg_destroy can do an error exit, but why assume anything...) */ fclose(infile); /* At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.pub.num_warnings is nonzero). */ /* And we're done! */ return 1; }
int main(int argc, char **argv) { try{ /* Set some default behaviors. */ const char *i = "latlong"; const char *o = "latlong"; const char *p = "rgss"; const char *f = "linear"; float rot[3] = { 0.f, 0.f, 0.f }; int n = 1024; int c; /* Parse the command line options. */ const char* convtype=NULL; double convparameter = 0.0; while ((c = getopt(argc, argv, "i:o:p:n:f:c:x:y:z:")) != -1) switch (c) { case 'i': i = optarg; break; case 'o': o = optarg; break; case 'p': p = optarg; break; case 'f': f = optarg; break; case 'x': rot[0] = strtod(optarg, 0); break; case 'y': rot[1] = strtod(optarg, 0); break; case 'z': rot[2] = strtod(optarg, 0); break; case 'n': n = strtol(optarg, 0, 0); break; case 'c': { convtype = optarg; if(!strcmp(convtype, "phong") || !strcmp(convtype, "gauss") || !strcmp(convtype, "hanning") || !strcmp(convtype, "lanczos")) { try { convparameter = std::stod(argv[optind], 0); } catch (const std::exception& e) { return usage(argv[0]); } } else { return usage(argv[0]); } break; } default: return usage(argv[0]); } int num = 1; image *src = 0; image *dst = 0; image *tmp = 0; to_img img; to_env env; filter fil; /* Select the sampler. */ if (!strcmp(f, "linear")) fil = filter_linear; else if (!strcmp(f, "nearest")) fil = filter_nearest; else return usage(argv[0]); /* Read the input image. */ const int fileArgCt = 2; std::vector<const char*> inputFiles; inputFiles.insert(inputFiles.begin(), &argv[optind], &argv[argc-1]); if (optind + fileArgCt <= argc) { if (!strcmp(i, "cube")) { tmp = image_reader(inputFiles, 6); src = image_border(tmp); img = cube_to_img; } else if (!strcmp(i, "dome")) { src = image_reader(inputFiles, 1); img = dome_to_img; } else if (!strcmp(i, "hemi")) { src = image_reader(inputFiles, 1); img = hemi_to_img; } else if (!strcmp(i, "ball")) { src = image_reader(inputFiles, 1); img = ball_to_img; } else if (!strcmp(i, "latlong") || !strcmp(i, "llsquare")) { src = image_reader(inputFiles, 1); img = rect_to_img; } else return usage(argv[0]); } else return usage(argv[0]); /* Prepare the output image. */ if (src) { if (!strcmp(o, "cube")) { dst = image_alloc((num = 6), n, n, src->c); env = cube_to_env; } else if (!strcmp(o, "dome")) { dst = image_alloc((num = 1), n, n, src->c); env = dome_to_env; } else if (!strcmp(o, "hemi")) { dst = image_alloc((num = 1), n, n, src->c); env = hemi_to_env; } else if (!strcmp(o, "ball")) { dst = image_alloc((num = 1), n, n, src->c); env = ball_to_env; } else if (!strcmp(o, "latlong")) { dst = image_alloc((num = 1), n, 2 * n, src->c); env = rect_to_env; } else if (!strcmp(o, "llsquare")) { dst = image_alloc((num = 1), n, n, src->c); env = rect_to_env; } else return usage(argv[0]); } else { throw std::runtime_error("Failed to load file"); } /* Perform the remapping using the selected pattern. */ if (src && dst) { if (!strcmp(p, "cent")) process(src, dst, ¢_pattern, rot, fil, img, env, num); else if (!strcmp(p, "rgss")) process(src, dst, &rgss_pattern, rot, fil, img, env, num); else if (!strcmp(p, "box2")) process(src, dst, &box2_pattern, rot, fil, img, env, num); else if (!strcmp(p, "box3")) process(src, dst, &box3_pattern, rot, fil, img, env, num); else if (!strcmp(p, "box4")) process(src, dst, &box4_pattern, rot, fil, img, env, num); else return usage(argv[0]); /* Write the output. */ //image_writer(argv[optind + 1], dst, num); image_writer(argv[argc - 1], dst, num); } }catch (const std::runtime_error& e) { std::clog<<e.what()<<std::endl; } return 0; }
int main(int argc, char **argv) { /* Set some default behaviors. */ const char *i = "rect"; const char *o = "rect"; const char *p = "rgss"; const char *f = "linear"; float rot[3] = { 0.f, 0.f, 0.f }; int n = 1024; int c; /* Parse the command line options. */ while ((c = getopt(argc, argv, "i:o:p:n:f:x:y:z:")) != -1) switch (c) { case 'i': i = optarg; break; case 'o': o = optarg; break; case 'p': p = optarg; break; case 'f': f = optarg; break; case 'x': rot[0] = strtod(optarg, 0); break; case 'y': rot[1] = strtod(optarg, 0); break; case 'z': rot[2] = strtod(optarg, 0); break; case 'n': n = strtol(optarg, 0, 0); break; default: return usage(argv[0]); } int num = 1; image *src = 0; image *dst = 0; image *tmp = 0; to_img img; to_env env; filter fil; /* Select the sampler. */ if (!strcmp(f, "linear")) fil = filter_linear; else if (!strcmp(f, "nearest")) fil = filter_nearest; else return usage(argv[0]); /* Read the input image. */ if (optind + 2 <= argc) { if (!strcmp(i, "cube")) { tmp = image_reader(argv[optind], 6); src = image_border(tmp); img = cube_to_img; } else if (!strcmp(i, "dome")) { src = image_reader(argv[optind], 1); img = dome_to_img; } else if (!strcmp(i, "hemi")) { src = image_reader(argv[optind], 1); img = hemi_to_img; } else if (!strcmp(i, "ball")) { src = image_reader(argv[optind], 1); img = ball_to_img; } else if (!strcmp(i, "rect")) { src = image_reader(argv[optind], 1); img = rect_to_img; } else return usage(argv[0]); } else return usage(argv[0]); /* Prepare the output image. */ if (src) { if (!strcmp(o, "cube")) { dst = image_alloc((num = 6), n, n, src->c, src->b, src->s); env = cube_to_env; } else if (!strcmp(o, "dome")) { dst = image_alloc((num = 1), n, n, src->c, src->b, src->s); env = dome_to_env; } else if (!strcmp(o, "hemi")) { dst = image_alloc((num = 1), n, n, src->c, src->b, src->s); env = hemi_to_env; } else if (!strcmp(o, "ball")) { dst = image_alloc((num = 1), n, n, src->c, src->b, src->s); env = ball_to_env; } else if (!strcmp(o, "rect")) { dst = image_alloc((num = 1), n, 2 * n, src->c, src->b, src->s); env = rect_to_env; } else return usage(argv[0]); } /* Perform the remapping using the selected pattern. */ if (src && dst) { if (!strcmp(p, "cent")) process(src, dst, ¢_pattern, rot, fil, img, env, num); else if (!strcmp(p, "rgss")) process(src, dst, &rgss_pattern, rot, fil, img, env, num); else if (!strcmp(p, "box2")) process(src, dst, &box2_pattern, rot, fil, img, env, num); else if (!strcmp(p, "box3")) process(src, dst, &box3_pattern, rot, fil, img, env, num); else if (!strcmp(p, "box4")) process(src, dst, &box4_pattern, rot, fil, img, env, num); else return usage(argv[0]); /* Write the output. */ image_writer(argv[optind + 1], dst, num); } return 0; }