📄 gfxbmp.c
字号:
if(upWidth) *upWidth = ihead.biWidth; if(upHeight) *upHeight = ihead.biHeight; if(upPixelSize) *upPixelSize = ihead.biBitCount; return 0;}// Load BMP and create an surface the same type of that BMP// return the surface handle on success !!!// if pSurface != NULL the surface will be locked and return the lock info in pSurface// else the surface is not locked// if pWidth / pHeight is not NULL, the width / height value will be returned// return -1 on failure int gfx_LoadBMP_Surface(int fdGfxDev, GFX_SURFACE_LOCK_INFO_T *pSurface, UINT *pWidth, UINT *pHeight, const char * fname, BYTE alpha){ unsigned int uW, uH, uP; int hbmp, rtn; GFX_SURFACE_LOCK_INFO_T sbmp; GFX_PALETTE_T *pPal = NULL; if(gfx_GetBMPInfo(fname, &uW, &uH, &uP) < 0) { // invalid bmp return -1; } if(uP <= 8) // palette bmp { pPal = malloc(256*sizeof(GFX_PALETTE_T)); if(!pPal) { return -1; } } hbmp = -1; switch(uP) { case 1:#ifdef GFX_SURFACE_CLUT1BPP_ARGB hbmp = gfx_create_surface(fdGfxDev, uW, uH, GFX_SURFACE_CLUT1BPP_ARGB, GFX_VDEV_NULL, 0);#elif defined(GFX_SURFACE_RAW1BPP) hbmp = gfx_create_surface(fdGfxDev, uW, uH, GFX_SURFACE_RAW1BPP, GFX_VDEV_NULL, 0);#endif break; case 4: hbmp = gfx_create_surface(fdGfxDev, uW, uH, GFX_SURFACE_CLUT4BPP_ARGB, GFX_VDEV_NULL, 0); break; case 8: hbmp = gfx_create_surface(fdGfxDev, uW, uH, GFX_SURFACE_CLUT8BPP_ARGB, GFX_VDEV_NULL, 0); break; case 24: hbmp = gfx_create_surface(fdGfxDev, uW, uH, GFX_SURFACE_ARGB_8888, GFX_VDEV_NULL, 0); break; default: // unsupported BMP format free(pPal); return -1; } if(hbmp < 0) { if(pPal) free(pPal); return -1; } if(gfx_lock_surface(fdGfxDev, hbmp, &sbmp) < 0) { gfx_destroy_surface(fdGfxDev, hbmp); if(pPal) free(pPal); return -1; } switch(uP) { case 1: rtn = gfx_LoadBMP1b(&sbmp, pPal, 0, 0, uW, uH, fname, 0, 0, alpha); break; case 4: rtn = gfx_LoadBMP4b(&sbmp, pPal, 0, 0, uW, uH, fname, 0, 0, alpha); break; case 8: rtn = gfx_LoadBMP8b(&sbmp, pPal, 0, 0, uW, uH, fname, 0, 0, alpha); break; case 24: rtn = gfx_LoadBMP24b(&sbmp, 0, 0, uW, uH, fname, 0, 0, alpha); break; } if(rtn < 0) { if(pPal) free(pPal); gfx_unlock_surface(fdGfxDev, hbmp, &sbmp); gfx_destroy_surface(fdGfxDev, hbmp); return -1; } if(uP <= 8) // palette bmp { gfx_set_surface_palette(fdGfxDev, hbmp, 0, 1<<uP, pPal); free(pPal); } if(pSurface) { memcpy(pSurface, &sbmp, sizeof(GFX_SURFACE_LOCK_INFO_T)); } else { gfx_unlock_surface(fdGfxDev, hbmp, &sbmp); } if(pWidth) *pWidth = uW; if(pHeight) *pHeight = uH; return hbmp;}// targa 32bits ARGB format support, just for use of the alpha channel :-(/* Targa file header*/typedef struct __TARGAHDR__ { BYTE bIDFieldSize; /* Characters in ID field */ BYTE bClrMapType; /* Color map type */ BYTE bImageType; /* Image type */ BYTE lClrMapSpec[5]; /* Color map specification */ UINT16 wXOrigin; /* X origin */ UINT16 wYOrigin; /* Y origin */ UINT16 wWidth; /* Bitmap width */ UINT16 wHeight; /* Bitmap height */ BYTE bBitsPixel; /* Bits per pixel */ BYTE bImageDescriptor; /* Image descriptor */} TARGA_HDR;int gfx_LoadTGA32b_Surface(int fdGfxDev, GFX_SURFACE_LOCK_INFO_T *pSurface, UINT *pWidth, UINT *pHeight, const char * fname){ FILE *fp; TARGA_HDR thead; int htga; int x, y; GFX_SURFACE_LOCK_INFO_T stga; if(!fname || !fname[0]) return -1; fp=fopen(fname, "rb"); if(fp == NULL) return -1; thead.bIDFieldSize = (BYTE)fgetc(fp); thead.bClrMapType = (BYTE)fgetc(fp); thead.bImageType = (BYTE)fgetc(fp); fread(thead.lClrMapSpec, 5, 1, fp); thead.wXOrigin = fgetWord(fp, 1); thead.wYOrigin = fgetWord(fp, 1); thead.wWidth = fgetWord(fp, 1); thead.wHeight = fgetWord(fp, 1); thead.bBitsPixel = (BYTE)fgetc(fp); thead.bImageDescriptor = (BYTE)fgetc(fp); if ((thead.bImageType!=2) || (thead.bBitsPixel!=32) || thead.bClrMapType != 0) /* not an TGA 32 bits file*/ { fclose(fp); return -1; } htga = gfx_create_surface(fdGfxDev, (UINT)thead.wWidth, (UINT)thead.wHeight, GFX_SURFACE_ARGB_8888, GFX_VDEV_NULL, 0); if(htga < 0) { fclose(fp); return -1; } if(gfx_lock_surface(fdGfxDev, htga, &stga) < 0) { gfx_destroy_surface(fdGfxDev, htga); fclose(fp); return -1; } fseek(fp, sizeof(thead) + thead.bIDFieldSize, SEEK_SET); // the pixel is stored in BGRA byte sequence order, which is just reversed to our format :-( // I'm not care the right to left ones, this should be rare if(thead.bImageDescriptor & 0x20) { // top to bottom for(y=0; y<(int)thead.wHeight; y++) { BYTE *p; p = (BYTE *)stga.plane[0].pPlane + stga.plane[0].uBytePerLine*y; fread(p, 4, thead.wWidth, fp); for(x=0; x<thead.wWidth*4; x+=4) { BYTE t; t = p[x]; p[x] = p[x+3]; p[x+3] = t; t = p[x+1]; p[x+1] = p[x+2]; p[x+2] = t; } } } else { // bottom to up for(y=(int)thead.wHeight-1; y>=0; y--) { BYTE *p; p = (BYTE *)stga.plane[0].pPlane + stga.plane[0].uBytePerLine*y; fread(p, 4, thead.wWidth, fp); for(x=0; x<thead.wWidth*4; x+=4) { BYTE t; t = p[x]; p[x] = p[x+3]; p[x+3] = t; t = p[x+1]; p[x+1] = p[x+2]; p[x+2] = t; } } } fclose(fp); if(pSurface) { memcpy(pSurface, &stga, sizeof(GFX_SURFACE_LOCK_INFO_T)); } else { gfx_unlock_surface(fdGfxDev, htga, &stga); } if(pWidth) *pWidth = thead.wWidth; if(pHeight) *pHeight = thead.wHeight; return htga;}#ifdef __JPEG_LIB_READY__ // IJG's libjpeg 6bstruct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */};typedef struct my_error_mgr * my_error_ptr;METHODDEF(void) __my_error_exit (j_common_ptr cinfo){ /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ my_error_ptr myerr = (my_error_ptr) cinfo->err; /* Return control to the setjmp point */ longjmp(myerr->setjmp_buffer, 1);}int gfx_LoadJPEG_Surface(int fdGfxDev, GFX_SURFACE_LOCK_INFO_T *pSurface, UINT *pWidth, UINT *pHeight, const char * fname, BYTE alpha){ struct jpeg_decompress_struct cinfo; struct my_error_mgr __jerr; FILE * fp; /* source file */ BYTE * buf; JSAMPROW row_pointer[1]; BYTE isgray; int hjpg; GFX_SURFACE_LOCK_INFO_T sjpg; int i,j,k; if(!fname || !fname[0]) return -1; fp=fopen(fname, "rb"); if(fp == NULL) return -1; /* Step 1: allocate and initialize JPEG decompression object */ __jerr.pub.error_exit = __my_error_exit; cinfo.err = jpeg_std_error(&__jerr.pub); /* Establish the setjmp return context for my_error_exit to use. */ buf = NULL; hjpg = -1; sjpg.uPlaneConfig = 0; if (setjmp(__jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ if(sjpg.uPlaneConfig) { gfx_unlock_surface(fdGfxDev, hjpg, &sjpg); } if(hjpg >= 0) { gfx_destroy_surface(fdGfxDev, hjpg); } jpeg_destroy_decompress(&cinfo); fclose(fp); if(buf) free(buf); return -1; } /* Now we can initialize the JPEG decompression object. */ jpeg_create_decompress(&cinfo); /* Step 2: specify data source (eg, a file) */ jpeg_stdio_src(&cinfo, fp); /* Step 3: read file parameters with jpeg_read_header() */ (void) jpeg_read_header(&cinfo, (unsigned char)1); if(cinfo.num_components == 3 && cinfo.out_color_space == JCS_RGB) { hjpg = gfx_create_surface(fdGfxDev, cinfo.image_width, cinfo.image_height, GFX_SURFACE_ARGB_8888, GFX_VDEV_NULL, 0); if(hjpg < 0) { jpeg_destroy_decompress(&cinfo); fclose(fp); return -1; // can not allocate enough memory } isgray = 0; } else if(cinfo.num_components == 1 && cinfo.out_color_space == JCS_GRAYSCALE) { hjpg = gfx_create_surface(fdGfxDev, cinfo.image_width, cinfo.image_height, GFX_SURFACE_CLUT8BPP_ARGB, GFX_VDEV_NULL, 0); if(hjpg < 0) { jpeg_destroy_decompress(&cinfo); fclose(fp); return -1; // can not allocate enough memory } isgray = 1; } else { jpeg_destroy_decompress(&cinfo); fclose(fp); return -1; } if(gfx_lock_surface(fdGfxDev, hjpg, &sjpg) < 0) { gfx_destroy_surface(fdGfxDev, hjpg); jpeg_destroy_decompress(&cinfo); fclose(fp); return -1; } if(isgray) { int i; GFX_PALETTE_T *pPal = malloc(256*sizeof(GFX_PALETTE_T)); if(!pPal) { gfx_unlock_surface(fdGfxDev, hjpg, &sjpg); gfx_destroy_surface(fdGfxDev, hjpg); jpeg_destroy_decompress(&cinfo); fclose(fp); return -1; } for(i=0; i<256; i++) { pPal[i].a = alpha; pPal[i].r = i; pPal[i].g = i; pPal[i].b = i; } gfx_set_surface_palette(fdGfxDev, hjpg, 0, 256, pPal); free(pPal); } else { if ((buf = (BYTE *)malloc(cinfo.image_width*3)) == NULL) { gfx_unlock_surface(fdGfxDev, hjpg, &sjpg); gfx_destroy_surface(fdGfxDev, hjpg); jpeg_destroy_decompress(&cinfo); fclose(fp); return -1; } // can not allocate buffer } /* Step 4: set parameters for decompression */ /* Step 5: Start decompressor */ (void) jpeg_start_decompress(&cinfo); /* Step 6: while (scan lines remain to be read) */ /* jpeg_read_scanlines(...); */ if(isgray) { BYTE * cr; cr = (BYTE *)sjpg.plane[0].pPlane; k=0; while (cinfo.output_scanline < cinfo.output_height) { row_pointer[0] = cr+ k*sjpg.plane[0].uBytePerLine; k++; (void) jpeg_read_scanlines(&cinfo, row_pointer, 1); } } else { BYTE * cr, *base; base = (BYTE *)sjpg.plane[0].pPlane; row_pointer[0] = buf; while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, row_pointer, 1); cr = base; for(i=0,j=0, k=0; i<(int)cinfo.image_width; i++) { cr[k++] = alpha; cr[k++] = buf[j++]; cr[k++] = buf[j++]; cr[k++] = buf[j++]; } base += sjpg.plane[0].uBytePerLine; } } /* Step 7: Finish decompression */ (void) jpeg_finish_decompress(&cinfo); /* Step 8: Release JPEG decompression object */ jpeg_destroy_decompress(&cinfo); if(buf) free(buf); fclose(fp); if(pWidth) *pWidth = sjpg.plane[0].uWidth; if(pHeight) *pHeight = sjpg.plane[0].uHeight; if(pSurface) { memcpy(pSurface, &sjpg, sizeof(GFX_SURFACE_LOCK_INFO_T)); } else { gfx_unlock_surface(fdGfxDev, hjpg, &sjpg); } return hjpg;}#endif// we are expecting bitmap file distinguished by .bmp or .tga suffixesint gfx_LoadBitmap_Surface(int fdGfxDev, GFX_SURFACE_LOCK_INFO_T *pSurface, UINT *pWidth, UINT *pHeight, const char * fname, BYTE alpha){ int lth; if(!fname || !fname[0]) return -1; if((lth = strlen(fname)) < 5) return -1; // we could not decide the suffix if(!strcasecmp(&fname[lth-4], ".BMP")) return gfx_LoadBMP_Surface(fdGfxDev, pSurface, pWidth, pHeight, fname, alpha); if(!strcasecmp(&fname[lth-4], ".TGA")) return gfx_LoadTGA32b_Surface(fdGfxDev, pSurface, pWidth, pHeight, fname);#ifdef __JPEG_LIB_READY__ // IJG's libjpeg 6b if(!strcasecmp(&fname[lth-4], ".JPG")) return gfx_LoadJPEG_Surface(fdGfxDev, pSurface, pWidth, pHeight, fname, alpha);#endif return -1; // unrecognized suffix}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -