📄 devimage.c
字号:
} /* 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 intLoadJPEG(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, long num_bytes) { if (num_bytes >= src->size) return; smgr.next_input_byte += num_bytes; smgr.bytes_in_buffer -= num_bytes; } static boolean resync_to_restart(j_decompress_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 = (void *)init_source; smgr.fill_input_buffer = (void *)fill_input_buffer; smgr.skip_input_data = (void *)skip_input_data; smgr.resync_to_restart = (void *)resync_to_restart; smgr.term_source = (void *)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. *//* This is a quick user defined function to read from the buffer instead of from the file pointer */static voidpng_read_buffer(png_structp pstruct, png_bytep pointer, png_size_t size){ bread(pstruct->io_ptr, pointer, size);}static intLoadPNG(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; } /* Set up the input function */ png_set_read_fn(state, src, png_read_buffer); /* png_init_io(state, src); */ png_set_sig_bytes(state, 8); png_read_info(state, pnginfo); png_get_IHDR(state, pnginfo, &width, &height, &bit_depth, &colourtype, NULL, NULL, NULL); if(colourtype==PNG_COLOR_TYPE_PALETTE) { int num_palette = 256; png_colorp palette; int idx; // png_get_PLTE(state, pnginfo, &palette, &num_palette); pimage->palsize=num_palette; pimage->palette=malloc(num_palette*sizeof(MWPALENTRY)); if(pimage->palette==NULL) return 0; for(idx=0; idx<num_palette; idx++) { pimage->palette[idx].r=0; // palette[idx].red; pimage->palette[idx].g=0; // palette[idx].green; pimage->palette[idx].b=0; // palette[idx].blue; } } pimage->width = width; pimage->height = height; pimage->bpp = bit_depth; //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 3Ltypedef 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 12static 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 intLoadBMP(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 intDecodeRLE8(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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -