⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devimage.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 4 页
字号:
	bseek(src, 0L, 0);

	if(!bgets(src,buf, 4)) return 0;

	if(!strcmp("P1\n", buf)) type = PNM_TYPE_PBM;
	else if(!strcmp("P2\n", buf)) type = PNM_TYPE_PGM;
	else if(!strcmp("P3\n", buf)) type = PNM_TYPE_PPM;
	else if(!strcmp("P4\n", buf)) {
		type = PNM_TYPE_PBM;
		binary = 1;
	}
	else if(!strcmp("P5\n", buf)) {
		type = PNM_TYPE_PGM;
		binary = 1;
	}
	else if(!strcmp("P6\n", buf)) {
		type = PNM_TYPE_PPM;
		binary = 1;
	}

	if(type == PNM_TYPE_NOTPNM) return 0;

	n = 0;
	while((p = bgets(src, buf, 256))) {
		if(*buf == '#') continue;
		if(type == PNM_TYPE_PBM) {
			if(sscanf(buf, "%i %i", &pimage->width,
					&pimage->height) == 2) {
				pimage->bpp = 1;
				gothdrs = 1;
				if(!(pimage->palette = malloc(
						sizeof(MWPALENTRY) * 2))) {
					EPRINTF("Out of memory\n");
					return 2;
				}
				pimage->palsize = 2;
				pimage->palette[0].r = 0xff;
				pimage->palette[0].g = 0xff;
				pimage->palette[0].b = 0xff;
				pimage->palette[1].r = 0;
				pimage->palette[1].g = 0;
				pimage->palette[1].b = 0;
			}
			break;
		}
		if((type == PNM_TYPE_PGM) || (type == PNM_TYPE_PPM)) {
			if(!n++) {
				if(sscanf(buf, "%i %i", &pimage->width,
					&pimage->height) != 2) break;
			} else {
				if(sscanf(buf, "%i", &i) != 1) break;
				pimage->bpp = 24;
				if(i > 255) {
					EPRINTF("LoadPNM: PPM files must be "
						"24bpp\n");
					return 2;
				}
				for(scale = 7, n = 2; scale; scale--, n *= 2)
					if(i < n) break;
				gothdrs = 1;
				break;
			}
		}
	}

	if(!gothdrs) {
		EPRINTF("LoadPNM: bad image headers\n");
		if(pimage->palette) free(pimage->palette);
		return 2;
	}

	pimage->planes = 1;
	ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
						&pimage->bytesperpixel);
	pimage->compression = MWIMAGE_RGB;
	if(!(pimage->imagebits = malloc(pimage->pitch * pimage->height))) {
		EPRINTF("LoadPNM: couldn't allocate memory for image\n");
		if(pimage->palette) free(pimage->palette);
		return 2;
	}

	p = pimage->imagebits;

	if(type == PNM_TYPE_PBM) {
		if(binary) {
			x = 0;
			y = 0;
			while((ch = bgetc(src)) != EOF) {
				for(i = 0; i < 8; i++) {
					mask = 0x80 >> i;
					if(ch & mask) *p |= mask;
					else *p &= ~mask;
					if(++x == pimage->width) {
						if(++y == pimage->height)
							return 1;
						p = pimage->imagebits - 1 +
							(y * pimage->pitch);
						x = 0;
						break;
					}
				}
				p++;
			}
		} else {
			n = 0;
			while((ch = bgetc(src)) != EOF) {
				if(isspace(ch)) continue;
				mask = 0x80 >> n;
				if(ch == '1') *p |= mask;
				else if(ch == '0') *p &= ~mask;
				else goto baddata;
				if(++n == 8) {
					n = 0;
					p++;
				}
				if(++x == pimage->width) {
					if(++y == pimage->height)
						return 1;
					p = pimage->imagebits +
						(y * pimage->pitch);
					n = 0;
					x = 0;
				}
			}
		}
	} else {
		while(1) {
			if(type == PNM_TYPE_PGM) {
				if(binary) {
					if((ch = bgetc(src)) == EOF)
						goto baddata;
				} else {
				  //					if(fscanf(fp, "%i", &ch) != 1)
						goto baddata;
				}
				*p++ = ch << scale;
				*p++ = ch << scale;
				*p++ = ch << scale;
			} else {
				if(binary) {
					if(((col1 = bgetc(src)) == EOF) ||
					 	((col2 = bgetc(src)) == EOF) ||
					 	((col3 = bgetc(src)) == EOF))
						goto baddata;
				} else {
				  //					if(fscanf(fp, "%i %i %i", &col1, &col2,
				  //								&col3) != 3)
						goto baddata;
				}
				*p++ = col1 << scale;
				*p++ = col2 << scale;
				*p++ = col3 << scale;
			}
			if(++x == pimage->width) {
				if(++y == pimage->height) return 1;
				p = pimage->imagebits + (y * pimage->pitch);
				x = 0;
			}
		}
	}

baddata:
	EPRINTF("LoadPNM: bad image data\n");
	free(pimage->imagebits);
	if(pimage->palette) free(pimage->palette);
	return 2;
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_PNM_SUPPORT) */

#if defined(HAVE_FILEIO) && defined(HAVE_XPM_SUPPORT)
struct xpm_cmap {
  char mapstr[3];
  long palette_entry;
  long color;
  struct xpm_cmap *next;
};

 
static long XPM_parse_color(char *color)
{
  /* This will parse the string into a color value of some sort */

  if (color[0] != '#')
    {
      if (!strcmp(color, "None"))
	return(-1); /* Transparent */
      else
	return(0); /* If its an X color, then we bail */
    }
  else
    {
      /* This is ugly! */

      char *sptr = color + 1;
      char rstr[5], gstr[5], bstr[5];
      long r,g,b;

      switch(strlen(sptr))
	{
	case 6:
	  return(strtol(sptr, NULL, 16));

	case 9: /* RRRGGGBBB */
	  strncpy(rstr, sptr, 3);
	  strncpy(gstr, sptr + 3, 3);
	  strncpy(bstr, sptr + 6, 3);

	  rstr[3] = 0;
	  gstr[3] = 0;
	  bstr[3] = 0;

	  r = strtol(rstr, NULL, 16) >> 4;
	  g = strtol(gstr, NULL, 16) >> 4;
	  b = strtol(bstr, NULL, 16) >> 4;

	  return( (long) ( r << 16 | g << 8 | b));

	case 12:
	  strncpy(rstr, sptr, 4);
	  strncpy(gstr, sptr + 4, 4);
	  strncpy(bstr, sptr + 8, 4);
	  
	  rstr[4] = 0;
	  gstr[4] = 0;
	  bstr[4] = 0;

	  r = strtol(rstr, NULL, 16) >> 8;
	  g = strtol(gstr, NULL, 16) >> 8;
	  b = strtol(bstr, NULL, 16) >> 8;
	  
	  return( (long) ( (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)));
	}
    }

  return(0);
}

/* A series of status indicators that let us know whats going on */
/* It could be an enum if you want */

#define LOAD_HEADER 1
#define LOAD_COLORS 2
#define LOAD_PALETTE 3
#define LOAD_PIXELS 4
#define LOAD_DONE 5

/* The magic that "should" indicate an XPM (does it really?) */
#define XPM_MAGIC "/* XPM */"
#define XPM_TRANSCOLOR 0x01000000

static int LoadXPM(buffer_t *src, PMWIMAGEHDR pimage, PSD psd) 
{
  struct xpm_cmap *colorheap = 0;  /* A "heap" of color structs */
  struct xpm_cmap *colormap[256];  /* A quick hash of 256 spots for colors */
  
  unsigned char *imageptr = 0;

  MWSCREENINFO sinfo;

  char xline[300];
  char dline[300];

  char *c;
  int a;

  int col, row, colors, cpp;
  int in_color = 0;
  int read_xline = 0;

  int status = LOAD_HEADER;

  /* Very first thing, get the screen info */
  GdGetScreenInfo(psd, &sinfo);

  for(a = 0; a < 256; a++)
    colormap[a] = 0;

  pimage->imagebits = NULL;
  pimage->palette = NULL;

  /* Start over at the beginning with the file */
  bseek(src, 0, SEEK_SET);
 
  bgets(src, xline, 300);
 
  /* Chop the EOL */
  xline[strlen(xline) - 1] = 0;

  /* Check the magic */
  if (strncmp(xline, XPM_MAGIC, sizeof(XPM_MAGIC))) return(0);

  while(!beof(src))
    {
      /* Get the next line from the file */
      bgets(src,xline, 300);
      xline[strlen(xline) - 1] = 0;

      /* Check it out */
      if (xline[0] == '/' && xline[1] == '*') /* Comment */
	continue;

      if (xline[0] != '\"')
	continue;

      /* remove the quotes from the line */
      for(c = xline + 1, a = 0; *c != '\"' && *c != 0; c++, a++)
	dline[a] = *c;

      dline[a] = 0;

      /* Is it the header? */
      if (status == LOAD_HEADER)
	{
	  sscanf(dline, "%i %i %i %i", &col, &row, &colors, &cpp);

	  pimage->width = col;
	  pimage->height = row;
	  pimage->planes = 1;

	  if (sinfo.bpp <= 8)
	    {
	      pimage->bpp = sinfo.bpp;
	      pimage->compression = 0;
	      pimage->transcolor = -1;
	    }
	  else
	    {
	      pimage->bpp = 32;
	      pimage->transcolor = XPM_TRANSCOLOR;
	      pimage->compression = MWIMAGE_BGR;	  
	    }

	  pimage->palsize = colors;

	  ComputePitch(pimage->bpp, col, &pimage->pitch, &pimage->bytesperpixel);

	  pimage->imagebits = malloc(pimage->pitch * pimage->height); 
	  imageptr = (unsigned char *) pimage->imagebits;

	  /* Allocate enough room for all the colors */
	  colorheap = (struct xpm_cmap *) malloc(colors * sizeof(struct xpm_cmap));

	  /* Allocate the palette space (if required) */

	  if (sinfo.bpp <= 8)
	      pimage->palette = malloc(256*sizeof(MWPALENTRY));

	  if (!colorheap)
	    {
	      EPRINTF("Couldn't allocate any memory for the colors\n");
	      return(0);
	    }

	  status = LOAD_COLORS;
	  in_color = 0;
	  continue;
	}

      /* Are we in load colors? */
      if (status == LOAD_COLORS)
	{
	  struct xpm_cmap *n;

	  char tstr[5];
	  char cstr[256];

	  unsigned char m;

	  c = dline;

	  /* Go at at least 1 charater, and then count until we have
	     two spaces in a row */

	  strncpy(tstr, c, cpp);

	  c += cpp;	  
	  for(; *c == '\t' || *c == ' '; c++); /* Skip over whitespace */

	  /* FIXME: We assume that a 'c' follows.  What if it doesn't? */
	  c +=2;
	  
	  tstr[cpp] = 0;

	  /* Now we put it into the array for easy lookup   */
	  /* We base it off the first charater, even though */
	  /* there may be up to 4                           */

	  m = tstr[0];
	  
	  if (colormap[m])
	    {
	      n = colormap[m];
	      
	      while(n->next) n = n->next;
	      n->next = &colorheap[in_color];
	      n = n->next;
	    }
	  else
	    {
	      colormap[m] = &colorheap[in_color];
	      n = colormap[m];
	    }
	  
	  n->next = 0;

	  /* Record the string */
	  strncpy(n->mapstr, tstr, cpp);
	  n->mapstr[cpp] = 0;

	  /* Now record the palette entry */
	  n->palette_entry = (long) in_color;

	  /* This is the color */
	  sscanf(c, "%65535s", cstr);

	  /* Turn it into a real value */
	  n->color = XPM_parse_color(cstr);

	  /* If we are in palette mode, then we need to */
	  /* load the palette (duh..) */

	  if (sinfo.bpp <= 8)
	    {
	      if (n->color == -1)
		{
		  pimage->transcolor = in_color;
		  n->color = -1;
		}
		
	      pimage->palette[in_color].r = (n->color >> 16) & 0xFF;
	      pimage->palette[in_color].g = (n->color >> 8) & 0xFF;
	      pimage->palette[in_color].b = n->color & 0xFF;  
	    }
	  else
	    {
	      if (n->color == -1)
		n->color = XPM_TRANSCOLOR;
	    }

	  if (++in_color == colors)
	    {
	      read_xline = 0;
	      status = LOAD_PIXELS;
	    }

	  continue;	 
	}
      
      if (status == LOAD_PIXELS)
      {
	int bytecount = 0;
	int bitcount = 0;
	long dwordcolor = 0;
	int i;
	char pxlstr[3];

	c = dline;
	
	while(*c)
	  {
	    unsigned char z = 0;

	    if (cpp == 1)
	      {		
		z = *c;
		
		if (!colormap[z])
		  {
		    EPRINTF("No color entry for (%c)\n", z);
		    return(0);
		  }

		if (sinfo.bpp <= 8)
		  dwordcolor = (long) colormap[z]->palette_entry;
		else
		  dwordcolor = colormap[z]->color;	

		c++;
	      }
	    else
	      {
		struct xpm_cmap *n; 

		/* We grab the largest possible, and then compare */

		strncpy(pxlstr, c, cpp);
		z = pxlstr[0];

		if (!colormap[z])
		  {
		    EPRINTF("No color entry for (%s)\n", pxlstr);
		    return(0);
		  }
			
		n = colormap[z];

		while(n)
		  {
		    if (!strncmp(n->mapstr, pxlstr, cpp))
		      break;

		    n = n->next;
		  }

		if (!n)
		  {
		    EPRINTF("No color found for (%s)\n", pxlstr);	    
		    return(0);
		  }

		if (sinfo.bpp <= 8)
		  dwordcolor = (long) n->palette_entry;
		else
		  dwordcolor = n->color;
		
		c += cpp;
	      }

	    /* 
	     * This ugly thing is needed to ensure that we
	     * work well in all modes.
	     */
	    switch(sinfo.bpp)
	      {
	      case 2:
		if (bitcount == 0)
		  imageptr[0] = 0;
		
		imageptr[0] |= (dwordcolor & 0x3) << (4 - bitcount);
		bitcount++;
		
		if (bitcount == 4)
		  {
		    imageptr++;
		    bytecount += pimage->bytesperpixel;
		    bitcount = 0;
		  }
		
		break;

	      case 4:
		if (bitcount == 0)
		  imageptr[0] = 0;
		
		imageptr[0] |= (dwordcolor & 0xF) << (2 - bitcount);
		bitcount++;
		
		if (bitcount == 2)
		  {
		    imageptr++;
		    bytecount += pimage->bytesperpixel;
		    bitcount = 0;
		  }
		
		break;

	      case 8:
	      case 16:
	      case 24:
	      case 32:
	      
		for(i = 0; i < pimage->bytesperpixel; i++)
		  imageptr[i] = (dwordcolor >> (8 * i)) & 0xFF;
		
		imageptr += pimage->bytesperpixel;
		bytecount += pimage->bytesperpixel;
		break;

#ifdef NOTUSED
	      case 8:
		imageptr[0] = (unsigned char) (dwordcolor & 0xFF);
		imageptr += pimage->bytesperpixel;
		bytecount += pimage->bytesperpixel;
		break;

	      case 16:
	      case 24:
	      case 32:
		imageptr[0] = (unsigned char) (dwordcolor >> 24) & 0xFF;
		imageptr[1] = (unsigned char) (dwordcolor >> 16) & 0xFF;
		imageptr[2] = (unsigned char) (dwordcolor >> 8) & 0xFF;
		imageptr[3] = (unsigned char) (dwordcolor & 0xFF);
		imageptr += pimage->bytesperpixel;
		bytecount += pimage->bytesperpixel;
		break;
#endif
	      }
	  }

	/* Pad to the end of the line */
	if (bytecount < pimage->pitch)
	  for(i = 0; i < (pimage->pitch - bytecount); i++)
	    *imageptr++ = 0x00;

	read_xline++;
	
	if (read_xline == row)
	  status = LOAD_DONE;

	continue;
      }
    }

  free(colorheap);

  if (status != LOAD_DONE)
    return(-1);
  return(1);
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_XPM_SUPPORT)*/

#endif /* defined(HAVE_FILEIO)*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -