示例#1
0
int MDFN_SavePNGSnapshot(const char *fname, uint32 *fb, const MDFN_Rect *rect, uint32 pitch)
{
 int x, y;
 FILE *pp=NULL;
 uint8 *compmem = NULL;
 uLongf compmemsize = (uLongf)( (rect->h * (rect->w + 1) * 3 * 1.001 + 1) + 12 );

 if(!(compmem=(uint8 *)MDFN_malloc(compmemsize, _("PNG compression buffer"))))
  return 0;

 if(!(pp=fopen(fname, "wb")))
 {
  return 0;
 }
 {
  static uint8 header[8]={137,80,78,71,13,10,26,10};
  if(fwrite(header,8,1,pp)!=1)
   goto PNGerr;
 }

 {
  uint8 chunko[13];

  chunko[0] = rect->w >> 24;		// Width
  chunko[1] = rect->w >> 16;
  chunko[2] = rect->w >> 8;
  chunko[3] = rect->w;

  chunko[4] = rect->h >> 24;		// Height
  chunko[5] = rect->h >> 16;
  chunko[6] = rect->h >> 8;
  chunko[7] = rect->h;

  chunko[8]=8;				// 8 bits per sample(24 bits per pixel)
  chunko[9]=2;				// Color type; RGB triplet
  chunko[10]=0;				// compression: deflate
  chunko[11]=0;				// Basic adapative filter set(though none are used).
  chunko[12]=0;				// No interlace.

  if(!WritePNGChunk(pp,13,"IHDR",chunko))
   goto PNGerr;
 }

 {
  uint8 *tmp_buffer;
  uint8 *tmp_inc;
  tmp_inc = tmp_buffer = (uint8 *)malloc((rect->w * 3 + 1) * rect->h);

  for(y=0;y<rect->h;y++)
  {
   *tmp_inc = 0;
   tmp_inc++;
   for(x=0;x<rect->w;x++)
   {
    int r,g,b;
    DECOMP_COLOR(*(uint32 *)((uint8 *)fb + (y + rect->y) * pitch + (x + rect->x) * 4), r, g, b);
    tmp_inc[0] = r;
    tmp_inc[1] = g;
    tmp_inc[2] = b;
    tmp_inc += 3;
   }
  }

  if(compress(compmem, &compmemsize, tmp_buffer, rect->h * (rect->w * 3 + 1))!=Z_OK)
  {
   if(tmp_buffer) free(tmp_buffer);
   goto PNGerr;
  }
  if(tmp_buffer) free(tmp_buffer);
  if(!WritePNGChunk(pp,compmemsize,"IDAT",compmem))
   goto PNGerr;
 }
 if(!WritePNGChunk(pp,0,"IEND",0))
  goto PNGerr;

 free(compmem);
 fclose(pp);

 return 1;

 PNGerr:
 if(compmem)
  free(compmem);
 if(pp)
  fclose(pp);
 return(0);
}
示例#2
0
int SaveSnapshot(void)
{
 char *fn=0;
 int totallines=FSettings.LastSLine-FSettings.FirstSLine+1;
 int x,u,y;
 FILE *pp=NULL;
 uint8 *compmem=NULL;
 unsigned long compmemsize=totallines*263+12;

 if(!(compmem=FCEU_malloc(compmemsize)))
  return 0;

 for(u=0;u<999;u++)
 {
  pp=fopen((fn=FCEU_MakeFName(FCEUMKF_SNAP,u,"png")),"rb");
  if(pp==NULL) break;
  fclose(pp);
 }

 if(!(pp=fopen(fn,"wb")))
  return 0;
 {
  static uint8 header[8]={137,80,78,71,13,10,26,10};
  if(fwrite(header,8,1,pp)!=1)
   goto PNGerr;
 }

 {
  uint8 chunko[13];

  chunko[0]=chunko[1]=chunko[3]=0;
  chunko[2]=0x1;			// Width of 256

  chunko[4]=chunko[5]=chunko[6]=0;
  chunko[7]=totallines;			// Height

  chunko[8]=8;				// bit depth
  chunko[9]=3;				// Color type; indexed 8-bit
  chunko[10]=0;				// compression: deflate
  chunko[11]=0;				// Basic adapative filter set(though none are used).
  chunko[12]=0;				// No interlace.

  if(!WritePNGChunk(pp,13,"IHDR",chunko))
   goto PNGerr;
 }

 {
  char pdata[256*3];

  //void FCEUD_GetPalette(uint8 i,uint8 *r, unsigned char *g, unsigned char *b);
  for(x=0;x<256;x++)
   FCEUD_GetPalette(x,(uint8*)(pdata+x*3),(unsigned char*)(pdata+x*3+1),(unsigned char*)(pdata+x*3+2));
   // static int WritePNGChunk(FILE *fp, uint32 size, char *type, uint8 *data)
  if(!WritePNGChunk(pp,256*3,"PLTE",(uint8 *)pdata))
   goto PNGerr;
 }

 {
  uint8 *tmp=XBuf+FSettings.FirstSLine*272+8;
  uint8 *dest,*mal,*mork;

  /* If memory couldn't be allocated, just use XBuf(screen contents
     will be corrupted for one frame, though.
  */
  if(!(mal=mork=dest=malloc((totallines<<8)+totallines)))
   mork=dest=XBuf;

  for(y=0;y<totallines;y++)
  {
   *dest=0;			// No filter.
   dest++;
   for(x=256;x;x--,tmp++,dest++)
    *dest=*tmp;
   tmp+=16;
  }

  if(compress(compmem,&compmemsize,mork,(totallines<<8)+totallines)!=Z_OK)
  {
   if(mal) free(mal);
   goto PNGerr;
  }
  if(mal) free(mal);
  if(!WritePNGChunk(pp,compmemsize,"IDAT",compmem))
   goto PNGerr;
 }
 if(!WritePNGChunk(pp,0,"IEND",0))
  goto PNGerr;

 free(compmem);
 fclose(pp);
#ifdef GP2X
 sync();
#endif

 return u+1;


 PNGerr:
 if(compmem)
  free(compmem);
 if(pp)
  fclose(pp);
 return(0);
}
示例#3
0
文件: common.cpp 项目: fnsroot/iNDS
int NDS_WritePNG(const char *fname, u8 *data)
{
	int x, y;
	int width=256;
	int height=192*2;
	u16 * bmp = (u16 *)data;
	FILE *pp=NULL;
	uint8 *compmem = NULL;
	uLongf compmemsize = (uLongf)( (height * (width + 1) * 3 * 1.001 + 1) + 12 );

	if(!(compmem=(uint8 *)malloc(compmemsize)))
		return 0;

	if(!(pp=fopen(fname, "wb")))
	{
		goto PNGerr;
	}
	{
		const uint8 header[8]={137,80,78,71,13,10,26,10};
		if(fwrite(header,8,1,pp)!=1)
			goto PNGerr;
	}

	{
		uint8 chunko[13];

		chunko[0] = width >> 24;		// Width
		chunko[1] = width >> 16;
		chunko[2] = width >> 8;
		chunko[3] = width;

		chunko[4] = height >> 24;		// Height
		chunko[5] = height >> 16;
		chunko[6] = height >> 8;
		chunko[7] = height;

		chunko[8]=8;				// 8 bits per sample(24 bits per pixel)
		chunko[9]=2;				// Color type; RGB triplet
		chunko[10]=0;				// compression: deflate
		chunko[11]=0;				// Basic adapative filter set(though none are used).
		chunko[12]=0;				// No interlace.

		if(!WritePNGChunk(pp,13,"IHDR",chunko))
			goto PNGerr;
	}

	{
		uint8 *tmp_buffer;
		uint8 *tmp_inc;
		tmp_inc = tmp_buffer = (uint8 *)malloc((width * 3 + 1) * height);

		for(y=0;y<height;y++)
		{
			*tmp_inc = 0;
			tmp_inc++;
			for(x=0;x<width;x++)
			{
				int r,g,b;
				u16 pixel = bmp[y*256+x];
				r = pixel>>10;
				pixel-=r<<10;
				g = pixel>>5;
				pixel-=g<<5;
				b = pixel;
				r*=255/31;
				g*=255/31;
				b*=255/31;
				tmp_inc[0] = b;
				tmp_inc[1] = g;
				tmp_inc[2] = r;
				tmp_inc += 3;
			}
		}

		if(compress(compmem, &compmemsize, tmp_buffer, height * (width * 3 + 1))!=Z_OK)
		{
			if(tmp_buffer) free(tmp_buffer);
			goto PNGerr;
		}
		if(tmp_buffer) free(tmp_buffer);
		if(!WritePNGChunk(pp,compmemsize,"IDAT",compmem))
			goto PNGerr;
	}
	if(!WritePNGChunk(pp,0,"IEND",0))
		goto PNGerr;

	free(compmem);
	fclose(pp);

	return 1;

PNGerr:
	if(compmem)
		free(compmem);
	if(pp)
		fclose(pp);
	return(0);
}