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

📄 devimage.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#define FASTJPEG	1	/* =1 for temp quick jpeg 8bpp display */#define HAVE_MMAP       1       /* =1 to use mmap if available         */#if defined(HAVE_FILEIO)	/* temp for entire file*//* * Copyright (c) 2000, 2001 Greg Haerr <greg@censoft.com> * Portions Copyright (c) 2000 Martin Jolicoeur <martinj@visuaide.com> * Portions Copyright (c) 2000 Alex Holden <alex@linuxhacker.org> * Portions Copyright (c) Independant JPEG group (ijg) * * Image load/cache/resize/display routines * * GIF, BMP, JPEG, PPM, PGM, PBM, PNG, and XPM formats are supported. * JHC:  Instead of working with a file, we work with a buffer *       (either provided by the user or through mmap).  This *	 improves speed, and provides a mechanism by which the *	 client can send image data directly to the engine  */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h> #ifdef HAVE_MMAP#include <sys/mman.h>#endif #include "device.h"#include "swap.h"/* cached image list*/typedef struct {	MWLIST		link;		/* link list*/	int		id;		/* image id*/	PMWIMAGEHDR	pimage;		/* image data*/	PSD		psd;		/* FIXME shouldn't need this*/} IMAGEITEM, *PIMAGEITEM;static MWLISTHEAD imagehead;		/* global image list*/static int nextimageid = 1;typedef struct {  /* structure for reading images from buffer   */  void *start;    /* The pointer to the beginning of the buffer */  int offset;     /* The current offset within the buffer       */  int size;       /* The total size of the buffer               */} buffer_t; static void ComputePitch(int bpp, int width, int *pitch, int *bytesperpixel);#if defined(HAVE_BMP_SUPPORT)static int  LoadBMP(buffer_t *src, PMWIMAGEHDR pimage);#endif#if defined(HAVE_JPEG_SUPPORT)static int  LoadJPEG(buffer_t *src, PMWIMAGEHDR pimage, PSD psd,		MWBOOL fast_grayscale);#endif#if defined(HAVE_PNG_SUPPORT)static int  LoadPNG(buffer_t *src, PMWIMAGEHDR pimage);#endif#if defined(HAVE_GIF_SUPPORT)static int  LoadGIF(buffer_t *src, PMWIMAGEHDR pimage);#endif#if defined(HAVE_PNM_SUPPORT)static int LoadPNM(buffer_t *src, PMWIMAGEHDR pimage);#endif#if defined(HAVE_XPM_SUPPORT)static int LoadXPM(buffer_t *src, PMWIMAGEHDR pimage, PSD psd) ;#endif/* * Buffered input functions to replace stdio functions */static voidbinit(void *in, int size, buffer_t *dest){	dest->start = in;	dest->offset = 0;	dest->size = size;} static intbseek(buffer_t *buffer, int offset, int whence){	int new;	switch(whence) {	case SEEK_SET:		if (offset >= buffer->size || offset < 0)			return(-1);		buffer->offset = offset;		return(0);	case SEEK_CUR:		new = buffer->offset + offset;		if (new >= buffer->size || new < 0)			return(-1);		buffer->offset = new;		return(0);	case SEEK_END:		if (offset >= buffer->size || offset > 0)			return(-1);		buffer->offset = (buffer->size - 1) - offset;		return(0);	default:		return(-1);	}}   static intbread(buffer_t *buffer, void *dest, int size){	int copysize = size;	if (buffer->offset == buffer->size)		return(0);	if (buffer->offset + size > buffer->size) 		copysize = (buffer->size - buffer->offset);	memcpy((void *)dest, (void *)(buffer->start + buffer->offset),copysize);	buffer->offset += copysize;	return(copysize);} static intbgetc(buffer_t *buffer){	int ch;	if (buffer->offset == buffer->size) 		return(EOF);	ch = *((unsigned char *) (buffer->start + buffer->offset));	buffer->offset++;	return(ch);} static char *bgets(buffer_t *buffer, char *dest, int size){	int i,o;	int copysize = size - 1;	if (buffer->offset == buffer->size) 		return(0);	if (buffer->offset + copysize > buffer->size) 		copysize = buffer->size - buffer->offset;	for(o=0, i=buffer->offset; i < buffer->offset + copysize; i++, o++) {		dest[o] = *((char *) (buffer->start + i));		if (dest[o] == '\n')			break;	}	buffer->offset = i + 1;	dest[o + 1] = 0;	return(dest);} static intbeof(buffer_t *buffer){	return (buffer->offset == buffer->size);} /* * Image decoding and display * NOTE: This routine and APIs will change in subsequent releases. * * Decodes and loads a graphics file, then resizes to width/height, * then displays image at x, y * If width/height == -1, don't resize, use image size. * Clipping is not currently supported, just stretch/shrink to fit. * */static int GdDecodeImage(PSD psd, buffer_t *src, int flags);intGdLoadImageFromBuffer(PSD psd, void *buffer, int size, int flags){	buffer_t src;	binit(buffer, size, &src);	return(GdDecodeImage(psd, &src, flags));}voidGdDrawImageFromBuffer(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width,	MWCOORD height, void *buffer, int size, int flags){	int id;	buffer_t src;	binit(buffer, size, &src);	id = GdDecodeImage(psd, &src, flags);	if (id) {		GdDrawImageToFit(psd, x, y, width, height, id);		GdFreeImage(id);	}}voidGdDrawImageFromFile(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width,	MWCOORD height, char *path, int flags){	int	id;	id = GdLoadImageFromFile(psd, path, flags);	if (id) {		GdDrawImageToFit(psd, x, y, width, height, id);		GdFreeImage(id);	}}intGdLoadImageFromFile(PSD psd, char *path, int flags){  int fd, id;  struct stat s;  void *buffer = 0;  buffer_t src;    fd = open(path, O_RDONLY);  if (fd < 0 || fstat(fd, &s) < 0) {    EPRINTF("GdLoadImageFromFile: can't open image: %s\n", path);    return(0);  }  #ifdef HAVE_MMAP  buffer = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);  if (!buffer) {    EPRINTF("GdLoadImageFromFile: Couldn't map image %s\n", path);    close(fd);    return(0);  }#else  buffer = malloc(s.st_size);  if (!buffer) {     EPRINTF("GdLoadImageFromFile: Couldn't load image %s\n", path);     close(fd);     return(0);  }    if (read(fd, buffer, s.st_size) != s.st_size) {    EPRINTF("GdLoadImageFromFile: Couldn't load image %s\n", path);    close(fd);    return(0);  }#endif  binit(buffer, s.st_size, &src);  id = GdDecodeImage(psd, &src, flags);  #ifdef HAVE_MMAP  munmap(buffer, s.st_size);#else  free(buffer);#endif  close(fd);  return(id);}static intGdDecodeImage(PSD psd, buffer_t * src, int flags){        int         loadOK = 0;        PMWIMAGEHDR pimage;        PIMAGEITEM  pItem;	/* allocate image struct*/	pimage = (PMWIMAGEHDR)malloc(sizeof(MWIMAGEHDR));	if(!pimage) {		return 0;	}	pimage->imagebits = NULL;	pimage->palette = NULL;	pimage->transcolor = -1L;#if defined(HAVE_BMP_SUPPORT)	if (loadOK == 0) 		loadOK = LoadBMP(src, pimage);#endif#if defined(HAVE_GIF_SUPPORT)	if (loadOK == 0) 		loadOK = LoadGIF(src, pimage);#endif#if defined(HAVE_JPEG_SUPPORT)	if (loadOK == 0) 		loadOK = LoadJPEG(src, pimage, psd, flags);#endif#if defined(HAVE_PNG_SUPPORT)	if (loadOK == 0) 		loadOK = LoadPNG(src, pimage);#endif#if defined(HAVE_PNM_SUPPORT)	if(loadOK == 0)		loadOK = LoadPNM(src, pimage);#endif#if defined(HAVE_XPM_SUPPORT)	if (loadOK == 0) 		loadOK = LoadXPM(src, pimage, psd);#endif	if (loadOK == 0) {		EPRINTF("GdLoadImageFromFile: unknown image type\n");		goto err;		/* image loading error*/	}	if (loadOK != 1)		goto err;		/* image loading error*/	/* allocate id*/	pItem = GdItemNew(IMAGEITEM);	if (!pItem)		goto err;	pItem->id = nextimageid++;	pItem->pimage = pimage;	pItem->psd = psd;	GdListAdd(&imagehead, &pItem->link);	return pItem->id;err:	free(pimage);	return 0;			/* image loading error*/}static PIMAGEITEMfindimage(int id){	PMWLIST		p;	PIMAGEITEM	pimagelist;	for (p=imagehead.head; p; p=p->next) {		pimagelist = GdItemAddr(p, IMAGEITEM, link);		if (pimagelist->id == id)			return pimagelist;	}	return NULL;}voidGdDrawImageToFit(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,	int id){	PIMAGEITEM	pItem;	PMWIMAGEHDR	pimage;	pItem = findimage(id);	if (!pItem)		return;	pimage = pItem->pimage;	/*	 * Display image, possibly stretch/shrink to resize	 */	if (height < 0)		height = pimage->height;	if (width < 0)		width = pimage->width;	if (height != pimage->height || width != pimage->width) {		MWCLIPRECT	rcDst;		MWIMAGEHDR	image2;		/* create similar image, different width/height*/		image2.width = width;		image2.height = height;		image2.planes = pimage->planes;		image2.bpp = pimage->bpp;		ComputePitch(pimage->bpp, width, &image2.pitch,			&image2.bytesperpixel);		image2.compression = pimage->compression;		image2.palsize = pimage->palsize;		image2.palette = pimage->palette;	/* already allocated*/		image2.transcolor = pimage->transcolor;		if( (image2.imagebits = malloc(image2.pitch*height)) == NULL) {			EPRINTF("GdDrawImageToFit: no memory\n");			return;		}		rcDst.x = 0;		rcDst.y = 0;		rcDst.width = width;		rcDst.height = height;		/* Stretch full soruce to destination rectangle*/		GdStretchImage(pimage, NULL, &image2, &rcDst);		GdDrawImage(psd, x, y, &image2);		free(image2.imagebits);	} else		GdDrawImage(psd, x, y, pimage);}voidGdFreeImage(int id){	PIMAGEITEM	pItem;	PMWIMAGEHDR	pimage;	pItem = findimage(id);	if (pItem) {		GdListRemove(&imagehead, &pItem->link);		pimage = pItem->pimage;		/* delete image bits*/		if(pimage->imagebits)			free(pimage->imagebits);		if(pimage->palette)			free(pimage->palette);		free(pimage);		GdItemFree(pItem);	}}MWBOOLGdGetImageInfo(int id, PMWIMAGEINFO pii){	PMWIMAGEHDR	pimage;	PIMAGEITEM	pItem;	int		i;	pItem = findimage(id);	if (!pItem) {		memset(pii, 0, sizeof(*pii));		return FALSE;	}	pimage = pItem->pimage;	pii->id = id;	pii->width = pimage->width;	pii->height = pimage->height;	pii->planes = pimage->planes;	pii->bpp = pimage->bpp;	pii->pitch = pimage->pitch;	pii->bytesperpixel = pimage->bytesperpixel;	pii->compression = pimage->compression;	pii->palsize = pimage->palsize;	if (pimage->palsize) {		if (pimage->palette) {			for (i=0; i<pimage->palsize; ++i)				pii->palette[i] = pimage->palette[i];		} else {			/* FIXME handle jpeg's without palette*/			GdGetPalette(pItem->psd, 0, pimage->palsize,				pii->palette);		}	}	return TRUE;}#define PIX2BYTES(n)	(((n)+7)/8)/* * compute image line size and bytes per pixel * from bits per pixel and width */static voidComputePitch(int bpp, int width, int *pitch, int *bytesperpixel){	int	linesize;	int	bytespp = 1;	if(bpp == 1)		linesize = PIX2BYTES(width);	else if(bpp <= 4)		linesize = PIX2BYTES(width<<2);	else if(bpp <= 8)		linesize = width;	else if(bpp <= 16) {		linesize = width * 2;		bytespp = 2;	} else if(bpp <= 24) {		linesize = width * 3;		bytespp = 3;	} else {		linesize = width * 4;		bytespp = 4;	}	/* rows are DWORD right aligned*/	*pitch = (linesize + 3) & ~3;	*bytesperpixel = bytespp;}/* * StretchImage - Resize an image * * Major portions from SDL Simple DirectMedia Layer by Sam Lantinga * Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga <slouken@devolution.com> * This a stretch blit implementation based on ideas given to me by *  Tomasz Cejner - thanks! :) *//*    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#define DEFINE_COPY_ROW(name, type)					\static void name(type *src, int src_w, type *dst, int dst_w)		\{									\	int i;								\	int pos, inc;							\	type pixel = 0;							\									\	pos = 0x10000;							\	inc = (src_w << 16) / dst_w;					\	for ( i=dst_w; i>0; --i ) {					\		while ( pos >= 0x10000L ) {				\			pixel = *src++;					\			pos -= 0x10000L;				\		}							\		*dst++ = pixel;						\		pos += inc;						\	}								\}DEFINE_COPY_ROW(copy_row1, unsigned char)DEFINE_COPY_ROW(copy_row2, unsigned short)DEFINE_COPY_ROW(copy_row4, unsigned long)static void copy_row3(unsigned char *src, int src_w, unsigned char *dst,	int dst_w){	int i;	int pos, inc;	unsigned char r = 0;	unsigned char g = 0;	unsigned char b = 0;	pos = 0x10000;	inc = (src_w << 16) / dst_w;	for ( i=dst_w; i>0; --i ) {		while ( pos >= 0x10000L ) {			b = *src++;			g = *src++;			r = *src++;			pos -= 0x10000L;		}		*dst++ = b;		*dst++ = g;		*dst++ = r;		pos += inc;	}}/* Perform a stretch blit between two image structs of the same format.*/voidGdStretchImage(PMWIMAGEHDR src, MWCLIPRECT *srcrect, PMWIMAGEHDR dst,	MWCLIPRECT *dstrect){	int pos, inc;	int bytesperpixel;	int dst_maxrow;	int src_row, dst_row;	MWUCHAR *srcp = 0;	MWUCHAR *dstp;	MWCLIPRECT full_src;	MWCLIPRECT full_dst;	if ( src->bytesperpixel != dst->bytesperpixel ) {		EPRINTF("GdStretchImage: bytesperpixel mismatch\n");		return;	}	/* Verify the blit rectangles */	if ( srcrect ) {		if ( (srcrect->x < 0) || (srcrect->y < 0) ||		     ((srcrect->x+srcrect->width) > src->width) ||		     ((srcrect->y+srcrect->height) > src->height) ) {			EPRINTF("GdStretchImage: invalid source rect\n");			return;		}	} else {		full_src.x = 0;		full_src.y = 0;		full_src.width = src->width;		full_src.height = src->height;		srcrect = &full_src;	}	if ( dstrect ) {		/* if stretching to nothing, return*/		if (!dstrect->width || !dstrect->height)			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;

⌨️ 快捷键说明

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