void output(field * temperature, int iter) { char filename[64]; // The actual write routine takes only the actual data // (without ghost layers) so we need array for that int height, width; double **full_data; int i; height = temperature->nx; width = temperature->ny; // Copy the inner data full_data = malloc_2d(height, width); for (i = 0; i < temperature->nx; i++) memcpy(full_data[i], &temperature->data[i + 1][1], temperature->ny * sizeof(double)); sprintf(filename, "%s_%04d.png", "heat", iter); save_png(full_data[0], height, width, filename, 'c'); free(full_data); }
int output_gd_png(void *_array, int width, int height, int depth, const char *filename, color colors[], int numColors) { int x, y; int (*array)[height][width] = _array; int color=0; // Draw to buffer gdImagePtr im; im = gdImageCreateTrueColor(width, height); for (y=0; y<height; y++) for (x=0; x<width; x++) { if ((*array)[y][x] == -1) color=0; else color=colors[(*array)[y][x]].hex; //return_color(colors, numColors, depth, (*array)[y][x]); gdImageSetPixel(im, x, y, color); } // Write to file save_png(im, filename); gdImageDestroy(im); return 0; }
void GrayScott::run() { // timer init and start double start = MPI_Wtime(); for (int i=0; i<nSteps_; ++i) { step(); } // timer end and output of time double end = MPI_Wtime(); double elapsed = end-start; if (world.rank == 0) { std::string sep = "_"; std::cout // << "performance: " << '\t' << world.size << '\t' << nthreads_ << '\t' << elapsed << '\t' << N_ << '\t' // << "\n*********\n" << std::endl; } save_png(); }
int save_thumb(int code,char *path) { // CreateScreenshot(code); int ret = 0; if(current_screenshot != NULL) ret = save_png(current_screenshot, path); return ret; }
static int save_thumb(char *path) { int ret = 0; if (current_screenshot != NULL) { ret = save_png(current_screenshot, path); SDL_FreeSurface(current_screenshot); current_screenshot = NULL; } return ret; }
int main() { #ifdef HAVE_JPEG gdImagePtr im, im2; FILE *fp; char path[2048]; fp=fopen("resampledbug.jpeg", "rb"); if (!fp) { fprintf(stderr, "Can't load /home/pierre/IM3801.jpg\n"); return 1; } im = gdImageCreateFromJpeg(fp); fclose(fp); if (!im) { fprintf(stderr, "Can't load TIFF image %s\n", path); return 1; } im2 = gdImageNeuQuant(im, 256, 3); if (im2) { gdImageSaveAlpha(im2, 1); save_png(im2, "a_nnquant.png"); gdImageDestroy(im2); } else { printf("neu quant failed.\n"); } gdImageTrueColorToPalette(im, 1, 256); gdImageSaveAlpha(im, 1); save_png(im, "a_jquant_dither.png"); gdImageDestroy(im); #else printf("JPEG support is required for this example. Please recompile GD with JPEG or change this example to use another format as input."); return 1; #endif return 0; }
void Image::savePNG(const std::string& fileName) { FileStreamPtr fin = g_resources.createFile(fileName); if(!fin) stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName)); fin->cache(); std::stringstream data; save_png(data, m_size.width(), m_size.height(), 4, (unsigned char*)getPixelData()); fin->write(data.str().c_str(), data.str().length()); fin->flush(); fin->close(); }
//================================================================================= // pkl_output //================================================================================= PKLExport int pkl_output(PKLImage pkl, FILE *out, PKL_FORMAT format) { switch(format){ case PKL_FORMAT_JPEG: return save_jpeg(pkl, out); case PKL_FORMAT_PNG: return save_png(pkl, out); case PKL_FORMAT_BITMAP: return save_bitmap(pkl, out); default: return(1); } return(1); }
void save_img(std::string filename, const Matrix<Color>& img) { std::size_t n = filename.size(); std::string extension3 = filename.substr(n-3, n); std::string extension4 = filename.substr(n-4, n); if(!extension3.compare("bmp")) { save_bmp(filename, img); } else if(!extension3.compare("gif")) { save_gif(filename, img); } else if(!extension3.compare("ico")) { save_ico(filename, img); } /*else if(!extension3.compare("jpg")) { save_jpeg(filename, img); }*/ else if(!extension3.compare("pcx")) { save_pcx(filename, img); } else if(!extension3.compare("png")) { save_png(filename, img); } else if(!extension3.compare("pbm")) { save_pbm(filename, color2bwimage(img)); } else if(!extension3.compare("pgm")) { save_pgm(filename, color2grayimage(img)); } else if(!extension3.compare("ppm")) { save_ppm(filename, img); } else if(!extension3.compare("tga")) { save_tga(filename, img); } else if(!extension4.compare("tiff")) { save_tiff(filename, img); } }
int main() { gdImagePtr im, im2; FILE *fp; char path[2048]; fp=fopen("resampledbug.jpeg", "rb"); if (!fp) { fprintf(stderr, "Can't load /home/pierre/IM3801.jpg\n"); return 1; } im = gdImageCreateFromJpeg(fp); fclose(fp); if (!im) { fprintf(stderr, "Can't load TIFF image %s\n", path); return 1; } im2 = gdImageNeuQuant(im, 256, 3); if (im2) { gdImageSaveAlpha(im2, 1); save_png(im2, "a_nnquant.png"); gdImageDestroy(im2); } else { printf("neu quant failed.\n"); } gdImageTrueColorToPalette(im, 1, 256); gdImageSaveAlpha(im, 1); save_png(im, "a_jquant_dither.png"); gdImageDestroy(im); return 0; }
void output(field * temperature, int iter, parallel_data * parallel) { char filename[64]; // The actual write routine takes only the actual data // (without ghost layers) so we need array for that int height, width; double **full_data; double **tmp_data; // array for MPI sends and receives int i, p; height = temperature->nx * parallel->size; width = temperature->ny; tmp_data = malloc_2d(temperature->nx, temperature->ny); if (parallel->rank == 0) { // Copy the inner data full_data = malloc_2d(height, width); for (i = 0; i < temperature->nx; i++) memcpy(full_data[i], &temperature->data[i + 1][1], temperature->ny * sizeof(double)); // Receive data for (p = 1; p < parallel->size; p++) { MPI_Recv(&tmp_data[0][0], temperature->nx * temperature->ny, MPI_DOUBLE, p, 22, parallel->comm, MPI_STATUS_IGNORE); // Copy data to full array memcpy(&full_data[p * temperature->nx][0], tmp_data[0], temperature->nx * temperature->ny * sizeof(double)); } } else { // Send data for (i = 0; i < temperature->nx; i++) memcpy(tmp_data[i], &temperature->data[i + 1][1], temperature->ny * sizeof(double)); MPI_Send(&tmp_data[0][0], temperature->nx * temperature->ny, MPI_DOUBLE, 0, 22, parallel->comm); } if (parallel->rank == 0) { sprintf(filename, "%s_%04d.png", "heat", iter); save_png(full_data[0], height, width, filename, 'c'); free_2d(full_data); } free_2d(tmp_data); }
int main(int argc, char **argv) { auto bmp = load_image("test.png"); auto orig = bmp; //If the program crashes, try decreasing this number (it's senstive to [large] image size). matrix kernel = binomial(9); Pool pool; auto start = now(); conv(pool, bmp, kernel); printf("Blurred in %d ms.\n", to_milliseconds(start, now())); save_png(bmp, "output.png"); return 0; }
int main() { gdImagePtr im, im2; im = gdImageCreateTrueColor(400, 400); if (!im) { fprintf(stderr, "Can't create 400x400 TC image\n"); return 1; } gdImageFilledRectangle(im, 19, 29, 390, 390, 0xFFFFFF); gdImageRectangle(im, 19, 29, 390, 390, 0xFF0000); save_png(im, "a1.png"); im2 = gdImageCropAuto(im, GD_CROP_SIDES); if (im2) { save_png(im2, "a2.png"); gdImageDestroy(im2); } gdImageDestroy(im); im = read_png("test_crop_threshold.png"); if (!im) { return 1; } im2 = gdImageCropThreshold(im, 0xFFFFFF, 0.6); if (im2) { save_png(im2, "a4.png"); gdImageDestroy(im2); } gdImageDestroy(im); return 0; }
void Graphic_Util::save_texture(Gfx_Texture* tex, string name) { std::cout << "Save file " << name << std::endl; glBindFramebuffer(GL_FRAMEBUFFER, tex->GetFramebufferId()); check(); glViewport (0, 0, tex->GetWidth(), tex->GetHeight()); check(); int size = (tex->GetWidth() + 1) * (tex->GetHeight() + 1) * 4; GLubyte res[size]; glReadPixels(0, 0, tex->GetWidth(), tex->GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &res); glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport ( 0, 0, w_width, w_height ); check(); save_png(name.c_str(), res, tex->GetWidth(), tex->GetHeight()); std::cout << "End save file " << name << std::endl; }
// Saves a screenshot to file, it return the filename the screenshot // was saved to. std::string Screenshot::make_screenshot() { Surface screen = Display::get_framebuffer()->make_screenshot(); if (screen) { std::string filename = get_filename(); log_info("Screenshot: Saving screenshot to: %1%", filename); save_png(filename, screen.get_data(), screen.get_width(), screen.get_height(), screen.get_pitch()); log_info("Screenshot: Screenshot is done."); return filename; } else { return std::string(); } }
void output(field * temperature, int iter, parallel_data * parallel) { char filename[64]; // The actual write routine takes only the actual data // (without ghost layers) so we need array for that int height, width; double **full_data; int coords[2]; int ix, jy; int i, p; height = temperature->nx_full; width = temperature->ny_full; if (parallel->rank == 0) { // Copy the inner data full_data = malloc_2d(height, width); for (i = 0; i < temperature->nx; i++) memcpy(full_data[i], &temperature->data[i + 1][1], temperature->ny * sizeof(double)); // Receive data for (p = 1; p < parallel->size; p++) { MPI_Cart_coords(parallel->comm, p, 2, coords); ix = coords[0] * temperature->nx; jy = coords[1] * temperature->ny; MPI_Recv(&full_data[ix][jy], 1, parallel->subarraytype, p, 22, parallel->comm, MPI_STATUS_IGNORE); } } else { // Send data MPI_Ssend(&temperature->data[1][1], 1, parallel->subarraytype, 0, 22, parallel->comm); } if (parallel->rank == 0) { sprintf(filename, "%s_%04d.png", "heat", iter); save_png(full_data[0], height, width, filename, 'c'); free_2d(full_data); } }
void GrayScott::run() { // timer init and start std::chrono::time_point<std::chrono::high_resolution_clock> start, end; start = std::chrono::high_resolution_clock::now(); for (int i=0; i<nSteps_; ++i) { step(); } // timer end and output of time end = std::chrono::high_resolution_clock::now(); double elapsed = std::chrono::duration<double>(end-start).count(); std::cout << "\n"; std::cout << "exec time: " << '\t' << elapsed << std::endl; std::cout << "\n"; save_png(); }
int save_thumb(int code,char *path) { SDL_Surface *thumb_screen; int scaling,xstart,ystart,xend,yend,w,h; if (code==SCREENSHOT){ scaling=1; xstart=0; ystart=0; yend=prSDLScreen->h; xend=prSDLScreen->w; w=prSDLScreen->w; h=prSDLScreen->h; } else { scaling=7; xstart=48; ystart=8; xend=320-48; yend=240-8; w=32; h=32; } thumb_screen=SDL_CreateRGBSurface(prSDLScreen->flags,w,h,prSDLScreen->format->BitsPerPixel,prSDLScreen->format->Rmask,prSDLScreen->format->Gmask,prSDLScreen->format->Bmask,prSDLScreen->format->Amask); int x; int y=ystart; unsigned short * src_pixel = (unsigned short*)prSDLScreen->pixels; unsigned short * dst_pixel = (unsigned short*)thumb_screen->pixels; unsigned short * scan_src_pixel = 0; /*printf("Save thumb with startx %d - starty %d - endx %d - endy %d w %d - h %d\n",xstart,xend,ystart,yend,w,h); printf("Thumb screen width %d \n",prSDLScreen->w); */ for (y=ystart; y < yend; y+=scaling) { scan_src_pixel = src_pixel + (prSDLScreen->w * y); for (x = xstart; x < xend; x+=scaling)*dst_pixel++ = scan_src_pixel[x]; } int ret=save_png(thumb_screen,path); printf("SAVED \n"); SDL_FreeSurface(thumb_screen); return ret; }
/*----------------------------------------------------------------------------*/ void save( const claw::graphic::image& img, const std::string& filename ) { std::cout << "== Saving pcx files ==" << std::endl; save_pcx( img, filename ); std::cout << "== Saving jpg files ==" << std::endl; save_jpeg( img, filename ); std::cout << "== Saving png files ==" << std::endl; save_png( img, filename ); std::cout << "== Saving bitmap files ==" << std::endl; save_bitmap( img, filename ); std::cout << "== Saving targa files ==" << std::endl; save_targa( img, filename ); std::cout << "== Saving xbm files ==" << std::endl; save_xbm( img, filename ); }
static int print_800frames(const char *frame, size_t offset, const char *end, const struct rdf_info *file_info) { static unsigned n = 0; unsigned sec, i; int ret = 0; const unsigned w = 1200, h = 800; time_t time = 0; char time_str[64], sec_str[16]; char img_fname[256]; gdImagePtr im; im = gdImageCreateTrueColor(w, h); gdImageFilledRectangle(im, 0, 0, w-1, h-1, 0x0); sec = offset / (40000*400); printf("Save picture #%u: begin at %lu (%lu frame, %u sec)\n", n++, offset, offset / 40000, sec); for(i = 0; i < h; i++){ write_row(im, i, frame, w/8); frame += FRAME_SIZE; if(frame > end){ printf("End of file\n"); ret++; break; } } snprintf(img_fname, sizeof(img_fname), "%s_%04d.png", file_info->name, sec); print_string(im, w, 10, file_info->exper); print_string(im, w, 30, file_info->station); time = file_info->time0 + sec; ctime_r(&time, time_str); time_str[strlen(time_str)-1] = 0; print_string(im, w, 50, time_str); sprintf(sec_str, "%02d:%02d", sec/60, sec%60); print_string(im, w, 70, sec_str); save_png(im, img_fname); gdImageDestroy(im); return ret; }
void save_snapshot(void) { char path[MAX_PATH]; sound_mute(1); #if (EMU_SYSTEM == NCDZ) mp3_pause(1); #endif #if USE_CACHE cache_sleep(1); #endif if (snap_no == -1) { FILE *fp; snap_no = 1; while (1) { sprintf(path, "%s/%s_%02d.png", screenshotDir, game_name, snap_no); if ((fp = fopen(path, "rb")) == NULL) break; fclose(fp); snap_no++; } } sprintf(path, "%s/%s_%02d.png", screenshotDir, game_name, snap_no); if (save_png(path)) ui_popup(TEXT(SNAPSHOT_SAVED_AS_x_PNG), game_name, snap_no++); #if USE_CACHE cache_sleep(0); #endif #if (EMU_SYSTEM == NCDZ) mp3_pause(0); #endif sound_mute(0); }
/*----------------------------------------------------------------------------*/ void save_png( const claw::graphic::image& img, const std::string& filename ) { std::cout << "not compressed, not interlaced" << std::endl; save_png( img, filename, claw::graphic::png::writer::options::no_compression, claw::graphic::png::writer::options::none ); std::cout << "best compression, not interlaced" << std::endl; save_png( img, filename, claw::graphic::png::writer::options::best_compression, claw::graphic::png::writer::options::none ); std::cout << "best speed compression, not interlaced" << std::endl; save_png( img, filename, claw::graphic::png::writer::options::best_speed, claw::graphic::png::writer::options::none ); std::cout << "default compression, not interlaced" << std::endl; save_png( img, filename, claw::graphic::png::writer::options::default_compression, claw::graphic::png::writer::options::none ); std::cout << "not compressed, interlaced" << std::endl; save_png( img, filename, claw::graphic::png::writer::options::no_compression, claw::graphic::png::writer::options::adam7 ); std::cout << "best compression, interlaced" << std::endl; save_png( img, filename, claw::graphic::png::writer::options::best_compression, claw::graphic::png::writer::options::adam7 ); std::cout << "best speed compression, interlaced" << std::endl; save_png( img, filename, claw::graphic::png::writer::options::best_speed, claw::graphic::png::writer::options::adam7 ); std::cout << "default compression, interlaced" << std::endl; save_png( img, filename, claw::graphic::png::writer::options::default_compression, claw::graphic::png::writer::options::adam7 ); }
void save(unsigned int *counters, int width, int height, char *filename, int verbose) { int i, j; double colour; unsigned int total = 0; double luminosity; unsigned int maxCount = 0; unsigned char *data; if (verbose) printf("\nProcessing results\n"); for (i = 0; i < width * height; i ++) { total += counters[i]; maxCount = counters[i] > maxCount ? counters[i] : maxCount; } luminosity = (double)total / (width * height); if (verbose) printf("\nTotal points: %d\nMaximum : %d\nAverage lum : %f\n", total, maxCount, luminosity); data = malloc(width * height); for (i = 0; i < height; i ++) { for (j = 0; j < width; j ++) { colour = ((double)counters[j * width + i] / (luminosity * 10)) * 255.0; data[i * width + j] = (unsigned char)(colour > 255 ? 255 : colour); } } if (verbose) printf("\nSaving to %s\n", filename); save_png(filename, data, width, height); free(data); }
int main(int argc, char **argv) { char *fn; int begin=0; int end=255; int size=10; int cpl=0; int cell=0; char autohinter=0; char seq=0; char alpha=0; char pack=0; FT_Library freetype; FT_Face face; int err; int i; char *out_fn="font.png"; char *def_fn=NULL; Font font; if(argc<2) { usage(); return 1; } while((i=getopt(argc, argv, "r:s:l:c:o:atvh?ed:p"))!=-1) { char *ptr; int temp; switch(i) { case 'r': if(!strcmp(optarg, "all")) { begin=0; end=0x110000; } else { if(!isdigit(optarg[0])) temp=-1; else { temp=strtol(optarg, &ptr, 0); if(ptr[0]!=',' || !isdigit(ptr[1])) temp=-1; } if(temp<0) { printf("Not a valid range: %s\n", optarg); exit(1); } else { begin=temp; end=strtol(ptr+1, NULL, 0); } } break; case 's': size=strtol(optarg, NULL, 0); break; case 'l': cpl=strtol(optarg, NULL, 0); break; case 'c': cell=strtol(optarg, NULL, 0); break; case 'o': out_fn=optarg; break; case 'a': autohinter=1; break; case 't': alpha=1; break; case 'v': ++verbose; break; case 'h': case '?': usage(); return 0; case 'e': seq=1; break; case 'd': def_fn=optarg; break; case 'p': pack=1; break; } } if(!strcmp(out_fn, "-")) verbose=0; if(optind!=argc-1) { usage(); return 1; } fn=argv[optind]; err=FT_Init_FreeType(&freetype); if(err) { fprintf(stderr, "Couldn't initialize FreeType library\n"); return 1; } err=FT_New_Face(freetype, fn, 0, &face); if(err) { fprintf(stderr, "Couldn't load font file\n"); if(err==FT_Err_Unknown_File_Format) fprintf(stderr, "Unknown file format\n"); return 1; } if(verbose) { const char *name=FT_Get_Postscript_Name(face); printf("Font name: %s\n", name); printf("Glyphs: %ld\n", face->num_glyphs); } err=FT_Set_Pixel_Sizes(face, 0, size); if(err) { fprintf(stderr, "Couldn't set size\n"); return 1; } font.size=size; init_font(&font, face, begin, end, autohinter); if(pack) render_packed(&font); else render_grid(&font, cell, cpl, seq); save_png(out_fn, &font.image, alpha); if(def_fn) save_defs(def_fn, &font); for(i=0; i<font.n_glyphs; ++i) free(font.glyphs[i].image.data); free(font.glyphs); free(font.image.data); FT_Done_Face(face); FT_Done_FreeType(freetype); return 0; }
int eventFuncMenu(XEvent ev){ int i,j,k; switch(ev.type){ case ButtonPress: for ( i=0 ; i<MAX_PEN ; i++ ){ /* 太さ・色選択ウィンドウ上で押された? */ if ( ev.xany.window == pen_win[i] ){ /* ペンサイズを変更 */ for ( j=0 ; j<MAX_PEN ; j++ ){ XSetWindowBackground( dis, pen_win[j], UNSELECTED_COLOR1 ); XClearWindow(dis,pen_win[j]); } XSetWindowBackground( dis, pen_win[i], SELECTED_COLOR); XClearWindow(dis,pen_win[i]); remapFuncMenu(); current_pen = i*3+2; XSetLineAttributes(dis, gc, current_pen, current_line, current_cap, current_join); XSetLineAttributes(dis, mask_gc, current_pen, current_line, current_cap, current_join); return(0); } } for ( i=0 ; i<MAX_COLOR ; i++ ){ if ( ev.xany.window == color_win[i] ){ /* 色を変更 */ current_color = GetColor(dis, color_name[i]); XSetForeground(dis, gc, current_color); return(0); } } if ( ev.xany.window == colors_win ){ /* 色を指定して変更 */ current_color = callColorSelect(dis, current_color,canvas); XSetForeground(dis, gc, current_color); remapCanvas(); remapFuncMenu(); return(0); } for ( i=0 ; i<MAX_FUNC ; i++ ){ if ( ev.xany.window == func_win[i] ){ /* 機能を変更 */ for ( j=0 ; j<MAX_FUNC ; j++ ){ XSetWindowBackground( dis, func_win[j], UNSELECTED_COLOR1 ); XClearWindow(dis,func_win[j]); } XSetWindowBackground( dis, func_win[i], SELECTED_COLOR); XClearWindow(dis,func_win[i]); remapFuncMenu(); state=i; setFuncSubWin(); return(0); } for ( j=0 ; j<MAX_FUNC_SUB ; j++ ){ if ( ev.xany.window == func_type_win[i][j] ){ /* 補助機能を変更 */ for ( k=0 ; k<MAX_FUNC_SUB ; k++ ){ XSetWindowBackground( dis, func_type_win[i][k], UNSELECTED_COLOR1 ); XClearWindow(dis,func_type_win[i][k]); } XSetWindowBackground( dis, func_type_win[i][j], SELECTED_COLOR); XClearWindow(dis,func_type_win[i][j]); remapFuncMenu(); sub_state=j; setFuncSubWin(); return(0); } } } for ( i=0 ; i<MAX_TYPE ; i++ ){ if ( ev.xany.window == line_type_win[i] ){ /* 線種を変更 */ switch(i){ case 0: XSetWindowBackground( dis, line_type_win[0], SELECTED_COLOR); XClearWindow(dis,line_type_win[0]); XSetWindowBackground( dis, line_type_win[1], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[1]); XSetWindowBackground( dis, line_type_win[2], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[2]); current_line=LineSolid; break; case 1: XSetWindowBackground( dis, line_type_win[0], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[0]); XSetWindowBackground( dis, line_type_win[1], SELECTED_COLOR); XClearWindow(dis,line_type_win[1]); XSetWindowBackground( dis, line_type_win[2], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[2]); current_line=LineOnOffDash; break; case 2: XSetWindowBackground( dis, line_type_win[0], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[0]); XSetWindowBackground( dis, line_type_win[1], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[1]); XSetWindowBackground( dis, line_type_win[2], SELECTED_COLOR); XClearWindow(dis,line_type_win[2]); current_line=LineDoubleDash; break; case 3: XSetWindowBackground( dis, line_type_win[3], SELECTED_COLOR); XClearWindow(dis,line_type_win[3]); XSetWindowBackground( dis, line_type_win[4], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[4]); XSetWindowBackground( dis, line_type_win[5], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[5]); current_cap=CapRound; break; case 4: XSetWindowBackground( dis, line_type_win[3], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[3]); XSetWindowBackground( dis, line_type_win[4], SELECTED_COLOR); XClearWindow(dis,line_type_win[4]); XSetWindowBackground( dis, line_type_win[5], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[5]); current_cap=CapButt; break; case 5: XSetWindowBackground( dis, line_type_win[3], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[3]); XSetWindowBackground( dis, line_type_win[4], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[4]); XSetWindowBackground( dis, line_type_win[5], SELECTED_COLOR); XClearWindow(dis,line_type_win[5]); current_cap=CapProjecting; break; case 6: XSetWindowBackground( dis, line_type_win[6], SELECTED_COLOR); XClearWindow(dis,line_type_win[6]); XSetWindowBackground( dis, line_type_win[7], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[7]); XSetWindowBackground( dis, line_type_win[8], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[8]); current_join=JoinMiter; break; case 7: XSetWindowBackground( dis, line_type_win[6], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[6]); XSetWindowBackground( dis, line_type_win[7], SELECTED_COLOR); XClearWindow(dis,line_type_win[7]); XSetWindowBackground( dis, line_type_win[8], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[8]); current_join=JoinRound; break; case 8: XSetWindowBackground( dis, line_type_win[6], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[6]); XSetWindowBackground( dis, line_type_win[7], UNSELECTED_COLOR2); XClearWindow(dis,line_type_win[7]); XSetWindowBackground( dis, line_type_win[8], SELECTED_COLOR); XClearWindow(dis,line_type_win[8]); current_join=JoinBevel; break; default: break; } remapFuncMenu(); XSetLineAttributes(dis, gc, current_pen, current_line, current_cap, current_join); XSetLineAttributes(dis, mask_gc, current_pen, current_line, current_cap, current_join); } } /***************************** デバッグ用 ********************************/ if ( ev.xany.window == debug_win ){ //printf("color=%d size=%d\n",current_color,current_pen); for(i=0;i<MAX_COLOR;i++) printf("%s %x\n",color_name[i],GetColor( dis, color_name[i])); printf("%x\n",GetColor(dis,"yellow")>>8&0xff); save_png(canvas); return(0); } /***************************** デバッグ用 *********************************/ break; case EnterNotify: /* ウィンドウにポインタが入った */ for ( i=0 ; i<MAX_PEN ; i++ ){ if ( ev.xany.window == pen_win[i] ){ /* ペンサイズ */ XSetWindowBorder(dis, ev.xany.window, OVERED_BORDERLINE_COLOR); return(0); } } for ( i=0 ; i<MAX_TYPE ; i++ ){ if ( ev.xany.window == line_type_win[i] ){ /* 線種 */ XSetWindowBorder(dis, ev.xany.window, OVERED_BORDERLINE_COLOR); return(0); } } for ( i=0 ; i<MAX_COLOR ; i++ ){ if ( ev.xany.window == color_win[i] ){ /* 色 */ XSetWindowBorder(dis, ev.xany.window, OVERED_BORDERLINE_COLOR); return(0); } } if ( ev.xany.window == colors_win ){ /* 色指定 */ XSetWindowBorder(dis, ev.xany.window, OVERED_BORDERLINE_COLOR); return(0); } for ( i=0 ; i<MAX_FUNC ; i++ ){ if ( ev.xany.window == func_win[i] ){ /* 機能 */ XSetWindowBorder(dis, ev.xany.window, OVERED_BORDERLINE_COLOR); return(0); } for ( j=0 ; j<MAX_FUNC_SUB ; j++ ){ if ( ev.xany.window == func_type_win[i][j] ){ /* 補助機能 */ XSetWindowBorder(dis, ev.xany.window, OVERED_BORDERLINE_COLOR); return(0); } } } if ( ev.xany.window == debug_win ){ /* デバッグ */ XSetWindowBorder(dis, ev.xany.window, OVERED_BORDERLINE_COLOR); return(0); } break; case LeaveNotify: /* ウィンドウからポインタが出た */ for ( i=0 ; i<MAX_PEN ; i++ ){ if ( ev.xany.window == pen_win[i] ){ /* ペンサイズ */ XSetWindowBorder(dis, ev.xany.window, BORDERLINE_COLOR); return(0); } } for ( i=0 ; i<MAX_TYPE ; i++ ){ if ( ev.xany.window == line_type_win[i] ){ /* 線種 */ XSetWindowBorder(dis, ev.xany.window, BORDERLINE_COLOR); return(0); } } for ( i=0 ; i<MAX_COLOR ; i++ ){ if ( ev.xany.window == color_win[i] ){ /* 色 */ XSetWindowBorder(dis, ev.xany.window, BORDERLINE_COLOR); return(0); } } if ( ev.xany.window == colors_win ){ /* 色指定 */ XSetWindowBorder(dis, ev.xany.window, BORDERLINE_COLOR); return(0); } for ( i=0 ; i<MAX_FUNC ; i++ ){ if ( ev.xany.window == func_win[i] ){ /* 機能 */ XSetWindowBorder(dis, ev.xany.window, BORDERLINE_COLOR); return(0); } for ( j=0 ; j<MAX_FUNC_SUB ; j++ ){ if ( ev.xany.window == func_type_win[i][j] ){ /* 補助機能 */ XSetWindowBorder(dis, ev.xany.window, BORDERLINE_COLOR); return(0); } } } if ( ev.xany.window == debug_win ){ /* デバッグ */ XSetWindowBorder(dis, ev.xany.window, BORDERLINE_COLOR); return(0); } break; default: break; } return(1); }
int main() { printf("\n\ntest_win_api_directx_research\n\n"); /* Retrieve a IDXGIFactory that can enumerate the adapters. */ IDXGIFactory1* factory = NULL; HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&factory)); if (S_OK != hr) { printf("Error: failed to retrieve the IDXGIFactory.\n"); exit(EXIT_FAILURE); } /* Enumerate the adapters.*/ UINT i = 0; IDXGIAdapter1* adapter = NULL; std::vector<IDXGIAdapter1*> adapters; /* Needs to be Released(). */ while (DXGI_ERROR_NOT_FOUND != factory->EnumAdapters1(i, &adapter)) { adapters.push_back(adapter); ++i; } /* Get some info about the adapters (GPUs). */ for (size_t i = 0; i < adapters.size(); ++i) { DXGI_ADAPTER_DESC1 desc; adapter = adapters[i]; hr = adapter->GetDesc1(&desc); if (S_OK != hr) { printf("Error: failed to get a description for the adapter: %lu\n", i); continue; } wprintf(L"Adapter: %lu, description: %s\n", i, desc.Description); } /* Check what devices/monitors are attached to the adapters. */ UINT dx = 0; IDXGIOutput* output = NULL; std::vector<IDXGIOutput*> outputs; /* Needs to be Released(). */ for (size_t i = 0; i < adapters.size(); ++i) { dx = 0; adapter = adapters[i]; while (DXGI_ERROR_NOT_FOUND != adapter->EnumOutputs(dx, &output)) { printf("Found monitor %d on adapter: %lu\n", dx, i); outputs.push_back(output); ++dx; } } if (0 >= outputs.size()) { printf("Error: no outputs found (%lu).\n", outputs.size()); exit(EXIT_FAILURE); } /* Print some info about the monitors. */ for (size_t i = 0; i < outputs.size(); ++i) { DXGI_OUTPUT_DESC desc; output = outputs[i]; hr = output->GetDesc(&desc); if (S_OK != hr) { printf("Error: failed to retrieve a DXGI_OUTPUT_DESC for output %lu.\n", i); continue; } wprintf(L"Monitor: %s, attached to desktop: %c\n", desc.DeviceName, (desc.AttachedToDesktop) ? 'y' : 'n'); } /* To get access to a OutputDuplication interface we need to have a Direct3D device which handles the actuall rendering and "gpu" stuff. According to a gamedev stackexchange it seems we can create one w/o a HWND. */ ID3D11Device* d3d_device = NULL; /* Needs to be released. */ ID3D11DeviceContext* d3d_context = NULL; /* Needs to be released. */ IDXGIAdapter1* d3d_adapter = NULL; D3D_FEATURE_LEVEL d3d_feature_level; /* The selected feature level (D3D version), selected from the Feature Levels array, which is NULL here; when it's NULL the default list is used see: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476082%28v=vs.85%29.aspx ) */ { /* Start creating a D3D11 device */ #if 1 /* NOTE: Apparently the D3D11CreateDevice function returns E_INVALIDARG, when you pass a pointer to an adapter for the first parameter and use the D3D_DRIVER_TYPE_HARDWARE. When you want to pass a valid pointer for the adapter, you need to set the DriverType parameter (2nd) to D3D_DRIVER_TYPE_UNKNOWN. @todo figure out what would be the best solution; easiest to use is probably using NULL here. */ int use_adapter = 0; if (use_adapter >= adapters.size()) { printf("Invalid adapter index: %d, we only have: %lu - 1\n", use_adapter, adapters.size()); exit(EXIT_FAILURE); } d3d_adapter = adapters[use_adapter]; if (NULL == d3d_adapter) { printf("Error: the stored adapter is NULL.\n"); exit(EXIT_FAILURE); } #endif hr = D3D11CreateDevice(d3d_adapter, /* Adapter: The adapter (video card) we want to use. We may use NULL to pick the default adapter. */ D3D_DRIVER_TYPE_UNKNOWN, /* DriverType: We use the GPU as backing device. */ NULL, /* Software: we're using a D3D_DRIVER_TYPE_HARDWARE so it's not applicaple. */ NULL, /* Flags: maybe we need to use D3D11_CREATE_DEVICE_BGRA_SUPPORT because desktop duplication is using this. */ NULL, /* Feature Levels (ptr to array): what version to use. */ 0, /* Number of feature levels. */ D3D11_SDK_VERSION, /* The SDK version, use D3D11_SDK_VERSION */ &d3d_device, /* OUT: the ID3D11Device object. */ &d3d_feature_level, /* OUT: the selected feature level. */ &d3d_context); /* OUT: the ID3D11DeviceContext that represents the above features. */ if (S_OK != hr) { printf("Error: failed to create the D3D11 Device.\n"); if (E_INVALIDARG == hr) { printf("Got INVALID arg passed into D3D11CreateDevice. Did you pass a adapter + a driver which is not the UNKNOWN driver?.\n"); } exit(EXIT_FAILURE); } } /* End creating a D3D11 device. */ /* Create a IDXGIOutputDuplication for the first monitor. - From a IDXGIOutput which represents an monitor, we query a IDXGIOutput1 because the IDXGIOutput1 has the DuplicateOutput feature. */ IDXGIOutput1* output1 = NULL; IDXGIOutputDuplication* duplication = NULL; { /* Start IDGIOutputDuplication init. */ int use_monitor = 0; if (use_monitor >= outputs.size()) { printf("Invalid monitor index: %d, we only have: %lu - 1\n", use_monitor, outputs.size()); exit(EXIT_FAILURE); } output = outputs[use_monitor]; if (NULL == output) { printf("No valid output found. The output is NULL.\n"); exit(EXIT_FAILURE); } hr = output->QueryInterface(__uuidof(IDXGIOutput1), (void**)&output1); if (S_OK != hr) { printf("Error: failed to query the IDXGIOutput1 interface.\n"); exit(EXIT_FAILURE); } hr = output1->DuplicateOutput(d3d_device, &duplication); if (S_OK != hr) { printf("Error: failed to create the duplication output.\n"); exit(EXIT_FAILURE); } printf("Queried the IDXGIOutput1.\n"); } /* End IDGIOutputDuplication init. */ if (NULL == duplication) { printf("Error: okay, we shouldn't arrive here but the duplication var is NULL.\n"); exit(EXIT_FAILURE); } /* To download the pixel data from the GPU we need a staging texture. Therefore we need to determine the width and height of the buffers that we receive. @TODO - We could also retrieve the width/height from the texture we got from through the acquired frame (see the 'tex' variable below). That may be a safer solution. */ DXGI_OUTPUT_DESC output_desc; { hr = output->GetDesc(&output_desc); if (S_OK != hr) { printf("Error: failed to get the DXGI_OUTPUT_DESC from the output (monitor). We need this to create a staging texture when downloading the pixels from the gpu.\n"); exit(EXIT_FAILURE); } printf("The monitor has the following dimensions: left: %d, right: %d, top: %d, bottom: %d.\n" ,(int)output_desc.DesktopCoordinates.left ,(int)output_desc.DesktopCoordinates.right ,(int)output_desc.DesktopCoordinates.top ,(int)output_desc.DesktopCoordinates.bottom ); } if (0 == output_desc.DesktopCoordinates.right || 0 == output_desc.DesktopCoordinates.bottom) { printf("The output desktop coordinates are invalid.\n"); exit(EXIT_FAILURE); } /* Create the staging texture that we need to download the pixels from gpu. */ D3D11_TEXTURE2D_DESC tex_desc; tex_desc.Width = output_desc.DesktopCoordinates.right; tex_desc.Height = output_desc.DesktopCoordinates.bottom; tex_desc.MipLevels = 1; tex_desc.ArraySize = 1; /* When using a texture array. */ tex_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; /* This is the default data when using desktop duplication, see https://msdn.microsoft.com/en-us/library/windows/desktop/hh404611(v=vs.85).aspx */ tex_desc.SampleDesc.Count = 1; /* MultiSampling, we can use 1 as we're just downloading an existing one. */ tex_desc.SampleDesc.Quality = 0; /* "" */ tex_desc.Usage = D3D11_USAGE_STAGING; tex_desc.BindFlags = 0; tex_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; tex_desc.MiscFlags = 0; ID3D11Texture2D* staging_tex = NULL; hr = d3d_device->CreateTexture2D(&tex_desc, NULL, &staging_tex); if (E_INVALIDARG == hr) { printf("Error: received E_INVALIDARG when trying to create the texture.\n"); exit(EXIT_FAILURE); } else if (S_OK != hr) { printf("Error: failed to create the 2D texture, error: %d.\n", hr); exit(EXIT_FAILURE); } /* Get some info about the output duplication. When the DesktopImageInSystemMemory is TRUE you can use the MapDesktopSurface/UnMapDesktopSurface directly to retrieve the pixel data. If not, then you need to use a surface. */ DXGI_OUTDUPL_DESC duplication_desc; duplication->GetDesc(&duplication_desc); printf("duplication desc.DesktopImageInSystemMemory: %c\n", (duplication_desc.DesktopImageInSystemMemory) ? 'y' : 'n'); /* Access a couple of frames. */ DXGI_OUTDUPL_FRAME_INFO frame_info; IDXGIResource* desktop_resource = NULL; ID3D11Texture2D* tex = NULL; DXGI_MAPPED_RECT mapped_rect; for (int i = 0; i < 500; ++i) { // printf("%02d - ", i); hr = duplication->AcquireNextFrame(1000, &frame_info, &desktop_resource); if (DXGI_ERROR_ACCESS_LOST == hr) { printf("Received a DXGI_ERROR_ACCESS_LOST.\n"); } else if (DXGI_ERROR_WAIT_TIMEOUT == hr) { printf("Received a DXGI_ERROR_WAIT_TIMEOUT.\n"); } else if (DXGI_ERROR_INVALID_CALL == hr) { printf("Received a DXGI_ERROR_INVALID_CALL.\n"); } else if (S_OK == hr) { //printf("Yay we got a frame.\n"); /* Print some info. */ //printf("frame_info.TotalMetadataBufferSize: %u\n", frame_info.TotalMetadataBufferSize); //printf("frame_info.AccumulatedFrames: %u\n", frame_info.AccumulatedFrames); /* Get the texture interface .. */ #if 1 hr = desktop_resource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&tex); if (S_OK != hr) { printf("Error: failed to query the ID3D11Texture2D interface on the IDXGIResource we got.\n"); exit(EXIT_FAILURE); } #endif /* Map the desktop surface */ hr = duplication->MapDesktopSurface(&mapped_rect); if (S_OK == hr) { printf("We got acess to the desktop surface\n"); hr = duplication->UnMapDesktopSurface(); if (S_OK != hr) { printf("Error: failed to unmap the desktop surface after successfully mapping it.\n"); } } else if (DXGI_ERROR_UNSUPPORTED == hr) { //printf("MapDesktopSurface returned DXGI_ERROR_UNSUPPORTED.\n"); /* According to the docs, when we receive this error we need to transfer the image to a staging surface and then lock the image by calling IDXGISurface::Map(). To get the data from GPU to the CPU, we do: - copy the frame into our staging texture - map the texture - ... do something - unmap. @TODO figure out what solution is faster: There are multiple solutions to copy a texture. I have to look into what solution is better. - d3d_context->CopySubresourceRegion(); - d3d_context->CopyResource(dest, src) @TODO we need to make sure that the width/height are valid. */ d3d_context->CopyResource(staging_tex, tex); D3D11_MAPPED_SUBRESOURCE map; HRESULT map_result = d3d_context->Map(staging_tex, /* Resource */ 0, /* Subresource */ D3D11_MAP_READ, /* Map type. */ 0, /* Map flags. */ &map); if (S_OK == map_result) { unsigned char* data = (unsigned char*)map.pData; //printf("Mapped the staging tex; we can access the data now.\n"); printf("RowPitch: %u, DepthPitch: %u, %02X, %02X, %02X\n", map.RowPitch, map.DepthPitch, data[0], data[1], data[2]); #if 0 if (i < 25) { char fname[512]; /* We have to make the image opaque. */ for (int k = 0; k < tex_desc.Width; ++k) { for (int l = 0; l < tex_desc.Height; ++l) { int dx = l * tex_desc.Width * 4 + k * 4; data[dx + 3] = 0xFF; } } sprintf(fname, "capture_%03d.png", i); save_png(fname, tex_desc.Width, tex_desc.Height, 8, PNG_COLOR_TYPE_RGBA, (unsigned char*)map.pData, map.RowPitch, PNG_TRANSFORM_BGR); } #endif } else { printf("Error: failed to map the staging tex. Cannot access the pixels.\n"); } d3d_context->Unmap(staging_tex, 0); } else if (DXGI_ERROR_INVALID_CALL == hr) { printf("MapDesktopSurface returned DXGI_ERROR_INVALID_CALL.\n"); } else if (DXGI_ERROR_ACCESS_LOST == hr) { printf("MapDesktopSurface returned DXGI_ERROR_ACCESS_LOST.\n"); } else if (E_INVALIDARG == hr) { printf("MapDesktopSurface returned E_INVALIDARG.\n"); } else { printf("MapDesktopSurface returned an unknown error.\n"); } } /* Clean up */ { if (NULL != tex) { tex->Release(); tex = NULL; } if (NULL != desktop_resource) { desktop_resource->Release(); desktop_resource = NULL; } /* We must release the frame. */ hr = duplication->ReleaseFrame(); if (S_OK != hr) { printf("Failed to release the duplication frame.\n"); } } } //printf("Monitors connected to adapter: %lu\n", i); /* Cleanup */ { if (NULL != staging_tex) { staging_tex->Release(); staging_tex = NULL; } if (NULL != d3d_device) { d3d_device->Release(); d3d_device = NULL; } if (NULL != d3d_context) { d3d_context->Release(); d3d_context = NULL; } if (NULL != duplication) { duplication->Release(); duplication = NULL; } for (size_t i = 0; i < adapters.size(); ++i) { if (NULL != adapters[i]) { adapters[i]->Release(); adapters[i] = NULL; } } for (size_t i = 0; i < outputs.size(); ++i) { if (NULL != outputs[i]) { outputs[i]->Release(); outputs[i] = NULL; } } if (NULL != output1) { output1->Release(); output1 = NULL; } if (NULL != factory) { factory->Release(); factory = NULL; } } return 0; }
//******************** M A I N ************************ void get_font(string FontName_base, char letter, int ptsize, vect2d *times) { _mkdir("font_rasters"); std::string FontName = "fonts/" + FontName_base + ".ttf"; char buf[256]; string letter_name; letter_name += letter; if (letter >= 'A' && letter <= 'Z') letter_name += letter; //----------------------------------------- // Load contour of glyph //----------------------------------------- lines.clear(); bez2s.clear(); FT_Face face; FT_Library library; FT_Error error; error = FT_Init_FreeType( &library ); Check(error, "", "error initializing FT lib"); error = FT_New_Face( library, FontName.c_str(), 0, &face ); Check(error, "", "error loading font"); FT_F26Dot6 font_size = ptsize*64; error = FT_Set_Char_Size( face, font_size, font_size, 72, 72 ); Check(error, "", "error setting char size"); FT_UInt glyph_index = FT_Get_Char_Index( face, letter ); FT_Int32 load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; error = FT_Load_Glyph( face, glyph_index, load_flags ); Check(error, "", "error loading glyph"); FT_Glyph glyph; error = FT_Get_Glyph( face->glyph, &glyph ); Check(error, "", "error getting glyph"); FT_OutlineGlyph Outg; error = GetOutLine(glyph, &Outg); Check(error,"", "error getting outline"); // use my own callcacks to walk over the contour FT_Outline_Funcs func_interface; func_interface.shift = 0; func_interface.delta = 0; func_interface.move_to = move_to; func_interface.line_to = line_to; func_interface.conic_to = conic_to; func_interface.cubic_to = cubic_to; FT_Outline_Decompose(&Outg->outline, &func_interface, 0); //----------------------------------------- // Rasterize using FreeType //----------------------------------------- // rasterize using FreeType so that a comparison to my code can be made double t_ft_start = get_time(); FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); double t_ft_stop = get_time(); // save timing FILE *fa = fopen("timings.txt", "a"); fprintf(fa, "time FreeType = %f\n", t_ft_stop - t_ft_start); fclose(fa); // create grid / calculate resolution g.max_depth = 0; g.grid_res = 2; int maxsize = max(face->glyph->bitmap.width, face->glyph->bitmap.rows); while (g.grid_res < maxsize) { g.grid_res *= 2; g.max_depth++; } vect2i offset; offset.set((g.grid_res - face->glyph->bitmap.width) / 2, (g.grid_res - face->glyph->bitmap.rows) / 2); // copy bitmap into a buffer Array2D<vect3ub> ftgrid; ftgrid.resize(g.grid_res, g.grid_res); for (int k = 0; k < g.grid_res*g.grid_res; k++) ftgrid.data[k].set(0); for (int j = 0; j < face->glyph->bitmap.rows; j++) { unsigned char *row = face->glyph->bitmap.buffer + (face->glyph->bitmap.rows-j-1)*face->glyph->bitmap.pitch; for (int i = 0; i < face->glyph->bitmap.width; i++) { ftgrid(i + offset[0], j + offset[1]) = row[i]; } } sprintf(buf, "font_rasters/%s_%04d_%s_1_ft.png", FontName_base.c_str(), ptsize, letter_name.c_str()); save_png(buf, ftgrid); //----------------------------------------- // Rasterize using our method //----------------------------------------- // get bbox FT_BBox bbox; FT_Outline_Get_BBox(&Outg->outline, &bbox); //printf("bbox = (%f, %f), (%f, %f)\n", bbox.xMin/64., bbox.yMin/64., bbox.xMax/64., bbox.yMax/64.); // fit in box vect2f ext; ext.set(bbox.xMax/64. - bbox.xMin/64., bbox.yMax/64. - bbox.yMin/64.); float maxext = std::max(ext[0], ext[1]) * 1.1; for (int i = 0; i < lines.s; i++) { //printf("line\n"); for (int j = 0; j < 2; j++) { lines[i][j][0] = (lines[i][j][0] - floor(bbox.xMin/64.) + offset[0]) / g.grid_res; lines[i][j][1] = (lines[i][j][1] - floor(bbox.yMin/64.) + offset[1]) / g.grid_res; //printf("%f %f\n", lines[i][j][0], lines[i][j][1]); } } for (int i = 0; i < bez2s.s; i++) { //printf("bez2\n"); for (int j = 0; j < 3; j++) { bez2s[i][j][0] = (bez2s[i][j][0] - floor(bbox.xMin/64.) + offset[0]) / g.grid_res; bez2s[i][j][1] = (bez2s[i][j][1] - floor(bbox.yMin/64.) + offset[1]) / g.grid_res; //printf("%f %f\n", bez2s[i][j][0], bez2s[i][j][1]); } } //vect3ub *grid = new vect3ub [g.grid_res*g.grid_res]; Array2D<float> grid; Array2D<vect3ub> ourgrid; grid.resize(g.grid_res, g.grid_res); ourgrid.resize(g.grid_res, g.grid_res); // rasterize for (int k = 0; k < g.grid_res*g.grid_res; k++) grid.data[k] = 0; double t_ours_start = get_time(); raster_poly(lines, bez2s, grid.data); double t_ours_stop = get_time(); // save timing FILE *f = fopen("timings.txt", "a"); fprintf(f, "time wavelet = %f\n", (t_ours_stop - t_ours_start)); fclose(f); // copy into color image and save for (int k = 0; k < g.grid_res*g.grid_res; k++) { if (grid.data[k] >= 1) ourgrid.data[k] = 255; else if (grid.data[k] <= 0) ourgrid.data[k] = 0; else ourgrid.data[k] = grid.data[k]*255; } sprintf(buf, "font_rasters/%s_%04d_%s_2_ours.png", FontName_base.c_str(), ptsize, letter_name.c_str()); save_png(buf, ourgrid); //----------------------------------------- // Calculate difference between renders //----------------------------------------- Array2D<vect3ub> grid_dif; grid_dif.resize(g.grid_res, g.grid_res); for (int i = 0; i < grid_dif.data_size; i++) { int dif = (grid.data[i]*255 - ftgrid.data[i][0]) * 10; if (dif > 255) dif = 255; else if (dif < -255) dif = -255; #if 1 grid_dif.data[i] = 255; if (dif < 0) { grid_dif.data[i][0] += dif; grid_dif.data[i][1] += dif; } else { grid_dif.data[i][1] -= dif; grid_dif.data[i][2] -= dif; } #else grid_dif.data[i] = 0; if (dif < 0) grid_dif.data[i][2] -= dif; else grid_dif.data[i][0] += dif; #endif } sprintf(buf, "font_rasters/%s_%04d_%s_3_dif.png", FontName_base.c_str(), ptsize, letter_name.c_str()); save_png(buf, grid_dif); //printf("--== timing comparison ==--\n"); //printf("time freetype = %f\n", t_ft_stop - t_ft_start); //printf("time wavelets = %f\n", t_ours_stop - t_ours_start); //printf("times slower = %f\n", (t_ours_stop - t_ours_start) / (t_ft_stop - t_ft_start) ); if (times) { times->v[0] += t_ft_stop - t_ft_start; times->v[1] += t_ours_stop - t_ours_start; } }
void Screenshot::save(SDL_Surface* surface, const std::string& filename) { std::unique_ptr<uint8_t[]> buffer(new uint8_t[surface->w * surface->h * 3]); #ifdef HAVE_OPENGL if(surface->flags & SDL_OPENGL) { glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, surface->w, surface->h, GL_RGB, GL_UNSIGNED_BYTE, buffer.get()); save_png(filename, buffer.get(), surface->w, surface->h, true); } else #endif { SDL_LockSurface(surface); switch(surface->format->BitsPerPixel) { case 16: // 16bit { uint8_t* pixels = static_cast<uint8_t*>(surface->pixels); for (int y = 0; y < surface->h; ++y) for (int x = 0; x < surface->w; ++x) { int i = (y * surface->w + x); SDL_GetRGB(*(reinterpret_cast<uint16_t*>(pixels + y * surface->pitch + x*2)), surface->format, buffer.get() + i*3 + 0, buffer.get() + i*3 + 1, buffer.get() + i*3 + 2); } break; } case 24: // 24bit { uint8_t* pixels = static_cast<uint8_t*>(surface->pixels); for (int y = 0; y < surface->h; ++y) for (int x = 0; x < surface->w; ++x) { int i = (y * surface->w + x); SDL_GetRGB(*(reinterpret_cast<uint32_t*>(pixels + y * surface->pitch + x*3)), surface->format, buffer.get() + i*3 + 0, buffer.get() + i*3 + 1, buffer.get() + i*3 + 2); } break; } case 32: // 32bit { uint8_t* pixels = static_cast<uint8_t*>(surface->pixels); for (int y = 0; y < surface->h; ++y) for (int x = 0; x < surface->w; ++x) { int i = (y * surface->w + x); SDL_GetRGB(*(reinterpret_cast<uint32_t*>(pixels + y * surface->pitch + x*4)), surface->format, buffer.get() + i*3 + 0, buffer.get() + i*3 + 1, buffer.get() + i*3 + 2); } break; } default: log_info("BitsPerPixel: " << int(surface->format->BitsPerPixel)); assert(!"Unknown color format"); break; } save_png(filename, buffer.get(), surface->w, surface->h); SDL_UnlockSurface(surface); } }
int main(int argc, char *argv[]){ unsigned int width = 1200, height = 800; double left = -2.0, down = -1.0, right = 1.0, up = 1.0; mandelbrot_type quality = 256; bool julia = false; double cx = 0.0, cy = 1.0; #ifdef BUILD_NETWORK_MASTER bool master = false; int port = 1573; #endif for (int i = 1; i < argc; i++){ if (!strcmp(argv[i], "--help")){ usage(); exit(EXIT_SUCCESS); } else if (!strcmp(argv[i], "-j")){ julia = true; down = -2.0; right = 2.0; up = 2.0; width = 800; } else if (!strcmp(argv[i], "-cx")){ if (i != argc-1) sscanf(argv[++i], "%lf", &cx); else error(); } else if (!strcmp(argv[i], "-cy")){ if (i != argc-1) sscanf(argv[++i], "%lf", &cy); else error(); } else if (!strcmp(argv[i], "-w")){ if (i != argc-1) sscanf(argv[++i], "%u", &width); else error(); } else if (!strcmp(argv[i], "-h")){ if (i != argc-1) sscanf(argv[++i], "%u", &height); else error(); } else if (!strcmp(argv[i], "-l")){ if (i != argc-1) sscanf(argv[++i], "%lf", &left); else error(); } else if (!strcmp(argv[i], "-d")){ if (i != argc-1) sscanf(argv[++i], "%lf", &down); else error(); } else if (!strcmp(argv[i], "-r")){ if (i != argc-1) sscanf(argv[++i], "%lf", &right); else error(); } else if (!strcmp(argv[i], "-u")){ if (i != argc-1) sscanf(argv[++i], "%lf", &up); else error(); } else if (!strcmp(argv[i], "-q")){ if (i != argc-1) sscanf(argv[++i], "%u", &quality); else error(); #ifdef _OPENMP } else if (!strcmp(argv[i], "-t")){ if (i != argc-1){ int threads; sscanf(argv[++i], "%d", &threads); omp_set_num_threads(threads); } else error(); #endif #ifdef BUILD_NETWORK_MASTER } else if (!strcmp(argv[i], "-n")) master = true; else if (!strcmp(argv[i], "-p")){ if (i != argc-1){ sscanf(argv[++i], "%d", &port); } else error(); #endif } } unsigned int size = width*height; mandelbrot_type *data = new mandelbrot_type[size]; std::fill(data, data + size, '\0'); #ifdef BUILD_NETWORK_MASTER if (master){ try { MandelbrotServer server( width, height, left, down, right, up, quality, data, port ); server.run(); } catch(...) { std::cerr << "Error in networking code" << std::endl; delete []data; exit(EXIT_FAILURE); } } else #endif { MandelbrotRenderer renderer( width, height, left, down, right, up, quality, data ); if (julia) renderer.set_julia_mode(cx, cy); clock_t time_start = clock(); renderer.render(); clock_t time_stop = clock(); std::cout << "Rendered in " << (double)(time_stop - time_start) / CLOCKS_PER_SEC << " seconds" << std::endl; } clock_t time_start = clock(); save_png(data, width, height, quality, "mandelbrot.png"); clock_t time_stop = clock(); std::cout << "Made PNG in " << (double)(time_stop - time_start) / CLOCKS_PER_SEC << " seconds" << std::endl; delete []data; return 0; }