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

📄 devimage.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 4 页
字号:
			return;
		if ( (dstrect->x < 0) || (dstrect->y < 0) ||
		     ((dstrect->x+dstrect->width) > dst->width) ||
		     ((dstrect->y+dstrect->height) > dst->height) ) {
			EPRINTF("GdStretchImage: invalid dest rect\n");
			return;
		}
	} else {
		full_dst.x = 0;
		full_dst.y = 0;
		full_dst.width = dst->width;
		full_dst.height = dst->height;
		dstrect = &full_dst;
	}

	/* Set up the data... */
	pos = 0x10000;
	inc = (srcrect->height << 16) / dstrect->height;
	src_row = srcrect->y;
	dst_row = dstrect->y;
	bytesperpixel = dst->bytesperpixel;

	/* Perform the stretch blit */
	for ( dst_maxrow = dst_row+dstrect->height; dst_row<dst_maxrow;
								++dst_row ) {
		dstp = (MWUCHAR *)dst->imagebits + (dst_row*dst->pitch)
				    + (dstrect->x*bytesperpixel);
		while ( pos >= 0x10000L ) {
			srcp = (MWUCHAR *)src->imagebits + (src_row*src->pitch)
				    + (srcrect->x*bytesperpixel);
			++src_row;
			pos -= 0x10000L;
		}

		switch (bytesperpixel) {
		case 1:
			copy_row1(srcp, srcrect->width, dstp, dstrect->width);
			break;
		case 2:
			copy_row2((unsigned short *)srcp, srcrect->width,
				(unsigned short *)dstp, dstrect->width);
			break;
		case 3:
			copy_row3(srcp, srcrect->width, dstp, dstrect->width);
			break;
		case 4:
			copy_row4((unsigned long *)srcp, srcrect->width,
				(unsigned long *)dstp, dstrect->width);
			break;
		}

		pos += inc;
	}
}

#if defined(HAVE_FILEIO) && defined(HAVE_JPEG_SUPPORT)
#include "jpeglib.h"
/*
 * JPEG decompression routine
 *
 * JPEG support must be enabled (see README.txt in contrib/jpeg)
 *
 * SOME FINE POINTS: (from libjpeg)
 * In the below code, we ignored the return value of jpeg_read_scanlines,
 * which is the number of scanlines actually read.  We could get away with
 * this because we asked for only one line at a time and we weren't using
 * a suspending data source.  See libjpeg.doc for more info.
 *
 * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
 * we should have done it beforehand to ensure that the space would be
 * counted against the JPEG max_memory setting.  In some systems the above
 * code would risk an out-of-memory error.  However, in general we don't
 * know the output image dimensions before jpeg_start_decompress(), unless we
 * call jpeg_calc_output_dimensions().  See libjpeg.doc for more about this.
 *
 * Scanlines are returned in the same order as they appear in the JPEG file,
 * which is standardly top-to-bottom.  If you must emit data bottom-to-top,
 * you can use one of the virtual arrays provided by the JPEG memory manager
 * to invert the data.  See wrbmp.c for an example.
 *
 * As with compression, some operating modes may require temporary files.
 * On some systems you may need to set up a signal handler to ensure that
 * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
 */
static int
LoadJPEG(buffer_t *src, PMWIMAGEHDR pimage, PSD psd, MWBOOL fast_grayscale)
{
  int 	i;
  int	ret = 2;	/* image load error*/
  unsigned char magic[4];

#if FASTJPEG
  extern MWPALENTRY mwstdpal8[256];
#else
  MWPALENTRY palette[256];
#endif

  struct jpeg_source_mgr smgr;
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  
  static void init_source(j_compress_ptr dinfo) {
    smgr.next_input_byte = src->start;
    smgr.bytes_in_buffer = src->size;
  }

  static void fill_input_buffer(j_compress_ptr dinfo) {
    return;
  }

  static void skip_input_data(j_compress_ptr dinfo, int num_bytes) {
    if (num_bytes >= src->size) return;
    smgr.next_input_byte += num_bytes;
    smgr.bytes_in_buffer -= num_bytes;
  }

  static int resync_to_restart(j_compress_ptr dinfo, int desired ) {
    return(jpeg_resync_to_restart(dinfo, desired));
  }

  static void term_source(j_compress_ptr dinfo) {
    return;
  }
	      
  /* first determine if JPEG file since decoder will error if not*/
  bseek(src, 0, SEEK_SET);
  
  if (!bread(src, magic, 2)) 
    return(0);
  
  if (magic[0] != 0xFF || magic[1] != 0xD8) 
    return(0);		/* not JPEG image*/
  
  
  bread(src, magic, 4);
  bread(src, magic, 4);
  
  if (strncmp(magic, "JFIF", 4) != 0) 
    return(0);		/* not JPEG image*/
  
  bread(src, 0, SEEK_SET);
  pimage->imagebits = NULL;
  pimage->palette = NULL;
  
  /* Step 1: allocate and initialize JPEG decompression object */
  
  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr);
  
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);
     
  
  /* Step 2:  Setup the source manager */

  smgr.init_source = init_source;
  smgr.fill_input_buffer = fill_input_buffer;
  smgr.skip_input_data = skip_input_data;
  smgr.resync_to_restart = resync_to_restart;
  smgr.term_source = term_source;
  
  cinfo.src = &smgr;

  /* Step 2: specify data source (eg, a file) */
  /* jpeg_stdio_src (&cinfo, fp); */
  
  /* Step 3: read file parameters with jpeg_read_header() */
  jpeg_read_header (&cinfo, TRUE);

	/* Step 4: set parameters for decompression */
	cinfo.out_color_space = fast_grayscale? JCS_GRAYSCALE: JCS_RGB;
	cinfo.quantize_colors = FALSE;

#if FASTJPEG
	goto fastjpeg;
#endif
	if (!fast_grayscale)
	{
		if (psd->pixtype == MWPF_PALETTE)
		{
fastjpeg:
			cinfo.quantize_colors = TRUE;

#if FASTJPEG
			cinfo.actual_number_of_colors = 256;
#else
			/* Get system palette */
			cinfo.actual_number_of_colors = 
				GdGetPalette(psd, 0, psd->ncolors, palette);
#endif
	
			/* Allocate jpeg colormap space */
			cinfo.colormap = (*cinfo.mem->alloc_sarray)
				((j_common_ptr) &cinfo, JPOOL_IMAGE,
			       	(JDIMENSION)cinfo.actual_number_of_colors,
				(JDIMENSION)3);

			/* Set colormap from system palette */
			for(i = 0; i < cinfo.actual_number_of_colors; ++i)
			{
#if FASTJPEG
				cinfo.colormap[0][i] = mwstdpal8[i].r;
				cinfo.colormap[1][i] = mwstdpal8[i].g;
				cinfo.colormap[2][i] = mwstdpal8[i].b;
#else
				cinfo.colormap[0][i] = palette[i].r;
				cinfo.colormap[1][i] = palette[i].g;
				cinfo.colormap[2][i] = palette[i].b;
#endif
			}
		}
	}
	else 
	{
		/* Grayscale output asked */
		cinfo.quantize_colors = TRUE;
		cinfo.out_color_space = JCS_GRAYSCALE;
		cinfo.desired_number_of_colors = psd->ncolors;
	}
	jpeg_calc_output_dimensions(&cinfo);

	pimage->width = cinfo.output_width;
	pimage->height = cinfo.output_height;
	pimage->planes = 1;
#if FASTJPEG
	pimage->bpp = 8;
#else
	pimage->bpp = (fast_grayscale || psd->pixtype == MWPF_PALETTE)?
		8: cinfo.output_components*8;
#endif
	ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
		&pimage->bytesperpixel);
	pimage->compression = MWIMAGE_RGB;	/* RGB not BGR order*/
	pimage->palsize = (pimage->bpp == 8)? 256: 0;
	pimage->imagebits = malloc(pimage->pitch * pimage->height);
	if(!pimage->imagebits)
		goto err;
	pimage->palette = NULL;
#if FASTJPEG
	if(pimage->bpp == 8) {
		pimage->palette = malloc(256*sizeof(MWPALENTRY));
		if(!pimage->palette)
			goto err;
		for (i=0; i<256; ++i)
			pimage->palette[i] = mwstdpal8[i];
	}
#endif

	/* Step 5: Start decompressor */
	jpeg_start_decompress (&cinfo);

	/* Step 6: while (scan lines remain to be read) */
	while(cinfo.output_scanline < cinfo.output_height) {
		JSAMPROW rowptr[1];
		rowptr[0] = (JSAMPROW)(pimage->imagebits +
			cinfo.output_scanline * pimage->pitch);
		jpeg_read_scanlines (&cinfo, rowptr, 1);
	}
	ret = 1;

err:
	/* Step 7: Finish decompression */
	jpeg_finish_decompress (&cinfo);

	/* Step 8: Release JPEG decompression object */
	jpeg_destroy_decompress (&cinfo);

	/* May want to check to see whether any corrupt-data
	 * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
	 */
	return ret;
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_JPEG_SUPPORT)*/

#if defined(HAVE_FILEIO) && defined(HAVE_PNG_SUPPORT)
#include "png.h"
/* png_jmpbuf() macro is not defined prior to libpng-1.0.6*/
#ifndef png_jmpbuf
#define png_jmpbuf(png_ptr)	((png_ptr)->jmpbuf)
#endif
/*
 * Load a PNG file.
 * Currently for simplicity we get the PNG library to convert the file to
 * 24 bit RGB format with no alpha channel information even if we could
 * potentially store the image more efficiently by taking note of the image
 * type and depth and acting accordingly. Similarly, > 8 bits per channel,
 * gamma correction, etc. are not supported.
 */
static int
LoadPNG(buffer_t * src, PMWIMAGEHDR pimage)
{
	unsigned char hdr[8], **rows;
	png_structp state;
	png_infop pnginfo;
	png_uint_32 width, height;
	int bit_depth, colourtype, i;

	bseek(src, 0L, 0);

	if(bread(src, hdr, 8) != 8) return 0;

	if(png_sig_cmp(hdr, 0, 8)) return 0;

	if(!(state = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, 
						NULL, NULL))) goto nomem;

	if(!(pnginfo = png_create_info_struct(state))) {
		png_destroy_read_struct(&state, NULL, NULL);
		goto nomem;
	}

	if(setjmp(png_jmpbuf(state))) {
		png_destroy_read_struct(&state, &pnginfo, NULL);
		return 2;
	}

	png_init_io(state, fp);
	png_set_sig_bytes(state, 8);
	png_read_info(state, pnginfo);
	png_get_IHDR(state, pnginfo, &width, &height, &bit_depth, &colourtype,
							NULL, NULL, NULL);

	pimage->width = width;
	pimage->height = height;
	pimage->bpp = 24;
	pimage->planes = 1;
	ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
						&pimage->bytesperpixel);
	pimage->compression = MWIMAGE_RGB;
        if(!(pimage->imagebits = malloc(pimage->pitch * pimage->height))) {
		png_destroy_read_struct(&state, &pnginfo, NULL);
		goto nomem;
        }
        if(!(rows = malloc(pimage->height * sizeof(unsigned char *)))) {
		png_destroy_read_struct(&state, &pnginfo, NULL);
		goto nomem;
        }
	for(i = 0; i < pimage->height; i++)
		rows[i] = pimage->imagebits + (i * pimage->pitch);

	png_set_expand(state);
	if(bit_depth == 16)
		png_set_strip_16(state);
	if(colourtype & PNG_COLOR_MASK_ALPHA)
		png_set_strip_alpha(state);
	if(colourtype == PNG_COLOR_TYPE_GRAY ||
			colourtype == PNG_COLOR_TYPE_GRAY_ALPHA)
		png_set_gray_to_rgb(state);

	png_read_image(state, rows);

	png_read_end(state, NULL);
	free(rows);
	png_destroy_read_struct(&state, &pnginfo, NULL);

	return 1;

nomem:
	EPRINTF("LoadPNG: Out of memory\n");
	return 2;
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_PNG_SUPPORT)*/

#if defined(HAVE_FILEIO) && defined(HAVE_BMP_SUPPORT)
/* BMP stuff*/
#define BI_RGB		0L
#define BI_RLE8		1L
#define BI_RLE4		2L
#define BI_BITFIELDS	3L

typedef unsigned char	BYTE;
typedef unsigned short	WORD;
typedef unsigned long	DWORD;
typedef long		LONG;

typedef struct {
	/* BITMAPFILEHEADER*/
	BYTE	bfType[2];
	DWORD	bfSize;
	WORD	bfReserved1;
	WORD	bfReserved2;
	DWORD	bfOffBits;
} BMPFILEHEAD;

#define FILEHEADSIZE 14

/* windows style*/
typedef struct {
	/* BITMAPINFOHEADER*/
	DWORD	BiSize;
	DWORD	BiWidth;
	DWORD	BiHeight;
	WORD	BiPlanes;
	WORD	BiBitCount;
	DWORD	BiCompression;
	DWORD	BiSizeImage;
	DWORD	BiXpelsPerMeter;
	DWORD	BiYpelsPerMeter;
	DWORD	BiClrUsed;
	DWORD	BiClrImportant;
} BMPINFOHEAD;

#define INFOHEADSIZE 40

/* os/2 style*/
typedef struct {
	/* BITMAPCOREHEADER*/
	DWORD	bcSize;
	WORD	bcWidth;
	WORD	bcHeight;
	WORD	bcPlanes;
	WORD	bcBitCount;
} BMPCOREHEAD;

#define COREHEADSIZE 12

static int	DecodeRLE8(MWUCHAR *buf, buffer_t *src);
static int	DecodeRLE4(MWUCHAR *buf, buffer_t *src);
static void	put4(int b);

/*
 * BMP decoding routine
 */

/* Changed by JHC to allow a buffer instead of a filename */

static int
LoadBMP(buffer_t *src, PMWIMAGEHDR pimage)
{
	int		h, i, compression;
	int		headsize;
	MWUCHAR		*imagebits;
	BMPFILEHEAD	bmpf;
	BMPINFOHEAD	bmpi;
	BMPCOREHEAD	bmpc;
	MWUCHAR 	headbuffer[INFOHEADSIZE];

	bseek(src, 0, SEEK_SET);

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

	/* read BMP file header*/
	if (bread(src, &headbuffer, FILEHEADSIZE) != FILEHEADSIZE)
	  return(0);

	bmpf.bfType[0] = headbuffer[0];
	bmpf.bfType[1] = headbuffer[1];

	/* Is it really a bmp file ? */
	if (*(WORD*)&bmpf.bfType[0] != wswap(0x4D42)) /* 'BM' */
		return 0;	/* not bmp image*/

	/*bmpf.bfSize = dwswap(dwread(&headbuffer[2]));*/
	bmpf.bfOffBits = dwswap(dwread(&headbuffer[10]));

	/* Read remaining header size */
	if (bread(src,&headsize,sizeof(DWORD)) != sizeof(DWORD))
		return 0;	/* not bmp image*/
	headsize = dwswap(headsize);

	/* might be windows or os/2 header */
	if(headsize == COREHEADSIZE) {

		/* read os/2 header */
		if(bread(src, &headbuffer, COREHEADSIZE-sizeof(DWORD)) !=
			COREHEADSIZE-sizeof(DWORD))
				return 0;	/* not bmp image*/

		/* Get data */
		bmpc.bcWidth = wswap(*(WORD*)&headbuffer[0]);
		bmpc.bcHeight = wswap(*(WORD*)&headbuffer[2]);
		bmpc.bcPlanes = wswap(*(WORD*)&headbuffer[4]);
		bmpc.bcBitCount = wswap(*(WORD*)&headbuffer[6]);
		
		pimage->width = (int)bmpc.bcWidth;
		pimage->height = (int)bmpc.bcHeight;
		pimage->bpp = bmpc.bcBitCount;
		if (pimage->bpp <= 8)
			pimage->palsize = 1 << pimage->bpp;
		else pimage->palsize = 0;
		compression = BI_RGB;
	} else {
		/* read windows header */
		if(bread(src, &headbuffer, INFOHEADSIZE-sizeof(DWORD)) !=
			INFOHEADSIZE-sizeof(DWORD))
				return 0;	/* not bmp image*/

		/* Get data */
		bmpi.BiWidth = dwswap(*(DWORD*)&headbuffer[0]);
		bmpi.BiHeight = dwswap(*(DWORD*)&headbuffer[4]);
		bmpi.BiPlanes = wswap(*(WORD*)&headbuffer[8]);
		bmpi.BiBitCount = wswap(*(WORD*)&headbuffer[10]);
		bmpi.BiCompression = dwswap(*(DWORD*)&headbuffer[12]);
		bmpi.BiSizeImage = dwswap(*(DWORD*)&headbuffer[16]);
		bmpi.BiXpelsPerMeter = dwswap(*(DWORD*)&headbuffer[20]);
		bmpi.BiYpelsPerMeter = dwswap(*(DWORD*)&headbuffer[24]);
		bmpi.BiClrUsed = dwswap(*(DWORD*)&headbuffer[28]);
		bmpi.BiClrImportant = dwswap(*(DWORD*)&headbuffer[32]);

		pimage->width = (int)bmpi.BiWidth;
		pimage->height = (int)bmpi.BiHeight;
		pimage->bpp = bmpi.BiBitCount;
		pimage->palsize = (int)bmpi.BiClrUsed;
		if (pimage->palsize > 256)
			pimage->palsize = 0;
		else if(pimage->palsize == 0 && pimage->bpp <= 8)
			pimage->palsize = 1 << pimage->bpp;
		compression = bmpi.BiCompression;
	}
	pimage->compression = MWIMAGE_BGR;	/* right side up, BGR order*/
	pimage->planes = 1;

	/* currently only 1, 4, 8 and 24 bpp bitmaps*/
	if(pimage->bpp > 8 && pimage->bpp != 24) {
		EPRINTF("LoadBMP: image bpp not 1, 4, 8 or 24\n");
		return 2;	/* image loading error*/
	}

	/* compute byte line size and bytes per pixel*/
	ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
		&pimage->bytesperpixel);

	/* Allocate image */
	if( (pimage->imagebits = malloc(pimage->pitch*pimage->height)) == NULL)
		goto err;
	if( (pimage->palette = malloc(256*sizeof(MWPALENTRY))) == NULL)
		goto err;

	/* get colormap*/
	if(pimage->bpp <= 8) {
		for(i=0; i<pimage->palsize; i++) {
			pimage->palette[i].b = bgetc(src);
			pimage->palette[i].g = bgetc(src);
			pimage->palette[i].r = bgetc(src);
			if(headsize != COREHEADSIZE)
				bgetc(src);
		}
	}

	/* decode image data*/
	bseek(src, bmpf.bfOffBits, SEEK_SET);

	h = pimage->height;
	/* For every row ... */
	while (--h >= 0) {
		/* turn image rightside up*/
		imagebits = pimage->imagebits + h*pimage->pitch;

		/* Get row data from file */
		if(compression == BI_RLE8) {
			if(!DecodeRLE8(imagebits, src))
				break;
		} else if(compression == BI_RLE4) {
			if(!DecodeRLE4(imagebits, src))
				break;
		} else {
			if(bread(src, imagebits, pimage->pitch) !=
				pimage->pitch)
					goto err;
		}
	}
	return 1;		/* bmp image ok*/
	
err:
	EPRINTF("LoadBMP: image loading error\n");
	if(pimage->imagebits)
		free(pimage->imagebits);
	if(pimage->palette)
		free(pimage->palette);
	return 2;		/* bmp image error*/
}

/*
 * Decode one line of RLE8, return 0 when done with all bitmap data
 */
static int
DecodeRLE8(MWUCHAR *buf, buffer_t *src)
{
	int		c, n;
	MWUCHAR *	p = buf;

	for( ;;) {
	  switch( n = bgetc(src)) {
	  case EOF:
	    return( 0);
	  case 0:			/* 0 = escape*/
	    switch( n = bgetc(src)) {
	    case 0: 	/* 0 0 = end of current scan line*/
	      return( 1);
	    case 1:		/* 0 1 = end of data*/
	      return( 1);
	    case 2:		/* 0 2 xx yy delta mode NOT SUPPORTED*/
	      (void)bgetc(src);
	      (void)bgetc(src);
	      continue;
	    default:	/* 0 3..255 xx nn uncompressed data*/
	      for( c=0; c<n; c++)
		*p++ = bgetc(src);
	      if( n & 1)
		(void)bgetc(src);
	      continue;
	    }
	  default:
	    c = bgetc(src);
	    while( n--)
	      *p++ = c;
	    continue;
	  }
	}
}

/*
 * Decode one line of RLE4, return 0 when done with all bitmap data
 */
static MWUCHAR *p;

⌨️ 快捷键说明

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