Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
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();
}
Exemple #4
0
int save_thumb(int code,char *path)
{
//	CreateScreenshot(code);
	int ret = 0;
	if(current_screenshot != NULL)
	  ret = save_png(current_screenshot, path);
	return ret;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
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();
}
Exemple #8
0
//=================================================================================
// 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);
    }
}
Exemple #10
0
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;
}
Exemple #11
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);
}
Exemple #12
0
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;
}
Exemple #13
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;
}
Exemple #14
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;
}
Exemple #15
0
// 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();
    }
}
Exemple #16
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;

    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);
    }
}
Exemple #17
0
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();
}
Exemple #18
0
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;
 }
Exemple #19
0
/*----------------------------------------------------------------------------*/
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 );
}
Exemple #20
0
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;
}
Exemple #21
0
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);
}
Exemple #22
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 );
}
Exemple #23
0
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);
}
Exemple #24
0
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;
}
Exemple #25
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;
}
Exemple #27
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);
  }
}
Exemple #29
0
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;
}