?? graphic_loader.c.svn-base
字號:
for(i=0 ; i<ptgBitmap->uiDataSize ; i++) { ptgBitmap->pData[i] = ((ptgBitmap->pData[i] & (0x3 << 0)) << 6) | ((ptgBitmap->pData[i] & (0x3 << 2)) << 2) | ((ptgBitmap->pData[i] & (0x3 << 4)) >> 2) | ((ptgBitmap->pData[i] & (0x3 << 6)) >> 6); } return RM_OK; break; case BMP_BPP_4 : // switch the MSB's and the LSB's of each bytes in a BITMAP's structure data array, // cause the graphic accelerator of mambo counts the bits in a byte like this : // 1 1 1 1 0 0 0 0 // and the bits in a bitmap are like this : // 0 0 0 0 1 1 1 1 for(i=0 ; i<ptgBitmap->uiDataSize ; i++) { ptgBitmap->pData[i] = ((ptgBitmap->pData[i] & (0xF << 0)) << 4) | ((ptgBitmap->pData[i] & (0xF << 4)) >> 4); } return RM_OK; break; case BMP_BPP_8 : case BMP_BPP_24 : case 32 : // no switch needed return RM_OK; break; default : //fprintf(stderr, "Unknown bpp.\n"); return RM_ERROR; break; }}RMbool isPng(RMascii *path){ RMascii buf[PNG_BYTES_TO_CHECK]; FILE *fp; // Open the prospective PNG file if ((fp = fopen(path, "rb")) == NULL){ return FALSE; } // Read in some of the signature bytes if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK) return FALSE; // Compare the first PNG_BYTES_TO_CHECK bytes of the signature. // Return nonzero (true) if they match fclose(fp); return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));}RMstatus load_png( struct RUA* pRua, RMbitmapdata *pBmpData, RMuint32 *bmpsize){ png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; FILE *fp; png_bytep *row_pointers; png_uint_32 row; int num_palette; png_colorp pal; RMuint32 datasize; RMstatus status; RMdrawBuffer bmpbuffer; RMuint8 channels; RMbool to32bpp = FALSE; // used if 24bpp to convert to 32bpp RMuint32 bufbyte, databyte; if ((fp = fopen(pBmpData->path, "rb")) == NULL) return RM_ERROR; // Create and initialize the png_struct with the desired error handler // functions. If you want to use the default stderr and longjump method, // you can supply NULL for the last three parameters. We also supply the // the compiler header file version, so that we know if the application // was compiled with a compatible version of the library. png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL){ fclose(fp); return RM_ERROR; } // Allocate/initialize the memory for image information. info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL){ fclose(fp); png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return RM_ERROR; } // Set error handling if you are using the setjmp/longjmp method (this is // the normal method of doing things with libpng). REQUIRED unless you // set up your own error handlers in the png_create_read_struct() earlier. if (setjmp(png_jmpbuf(png_ptr))){ // Free all of the memory associated with the png_ptr and info_ptr png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(fp); // If we get here, we had a problem reading the file return RM_ERROR; } png_init_io(png_ptr, fp); png_read_info(png_ptr, info_ptr); // this call prevent us from switching the bit ourselves as before (build 41) png_set_bgr(png_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); // this may be a 3 state button for which only a third of the horizontal size may be displayed if(height > g_OSDheight){ fprintf(stderr, "GFXLIB: PNG EXCEEDS OSD SURFACE SIZE [%s]\n", pBmpData->path); // clean up after the read, and free any memory allocated png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); // close the file fclose(fp); return RM_ERROR; }// printf("width = %ld, height = %ld, bpp = %d, color type = %d, interlaced = %d\n",// width, height, bit_depth, color_type, interlace_type); if(color_type == PNG_COLOR_TYPE_RGB) channels = 3; else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA) channels = 4; else if(color_type == PNG_COLOR_TYPE_PALETTE) channels = 1; else{ fprintf(stderr, "GFXLIB: UNSUPPORTED PNG [%s]\n", pBmpData->path); // clean up after the read, and free any memory allocated png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); // close the file fclose(fp); return RM_ERROR; } pBmpData->bmp.uiWidth = width; pBmpData->bmp.uiHeight = height; pBmpData->bmp.uiNbBitPerPixel = bit_depth * channels; pBmpData->bmp.uiWidthLenInBytes = width; datasize = width * height; // 24 bit not yet supported and has to be converted to 32 bit to32bpp = (pBmpData->bmp.uiNbBitPerPixel >= 24); if(to32bpp){ datasize = 4 * width * height; pBmpData->bmp.uiWidthLenInBytes = 4 * width; } else{ datasize = width * height; // adjust to 32bit datasize = datasize + datasize % 4; pBmpData->bmp.uiWidthLenInBytes = width; } *bmpsize = datasize; status = AllocateBuffer(&bmpbuffer, datasize, FALSE); if(RMFAILED(status)){ fprintf(stderr, "GFXLIB: NOT ENOUGH DRAM TO ALLOCATE PNG [%s]\n", pBmpData->path); // clean up after the read, and free any memory allocated png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); // close the file fclose(fp); return RM_FATALOUTOFMEMORY; } pBmpData->pBmpAddr = bmpbuffer.baseAddr; pBmpData->bmp.pData = bmpbuffer.pMappedAddr; pBmpData->bmp.uiDataSize = datasize; RMMemset(pBmpData->bmp.pData, 0xff, pBmpData->bmp.uiDataSize); png_read_update_info(png_ptr, info_ptr); row_pointers = png_malloc(png_ptr, sizeof(png_bytep)); RMMemset(row_pointers, 0, sizeof(png_bytep)); row_pointers[0] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); for (row = 0; row < height; row++){ png_read_row(png_ptr, row_pointers[0], NULL); if(to32bpp){ if(pBmpData->bmp.uiNbBitPerPixel == 32){ RMMemcpy(pBmpData->bmp.pData + row * width * 4, row_pointers[0], width * 4); // set alpha to 0xff if background if(pBmpData->isBackground){ for(databyte = 0, bufbyte = 0; databyte < 4 * width; databyte++){ if((databyte + 1) % 4 == 0) pBmpData->bmp.pData[databyte] = 0xff; } } } else{ // 24 to 32 bit for(databyte = 0, bufbyte = 0; databyte < 4 * width; databyte++){ if((databyte + 1) % 4 != 0) pBmpData->bmp.pData[databyte + row * 4 * width] = (row_pointers[0])[bufbyte++]; } } } else RMMemcpy(pBmpData->bmp.pData + row * width, row_pointers[0], width); } png_read_end(png_ptr, info_ptr); // read LUT if(pBmpData->bmp.uiNbBitPerPixel == 8){ num_palette = 256; pBmpData->bmp.uiPaletteSize = 1024; png_get_PLTE(png_ptr, info_ptr, &pal, &num_palette); for(row = 0; row < (png_uint_32)num_palette; row++){ pBmpData->bmp.palette[row].rgbRed = pal[row].red; pBmpData->bmp.palette[row].rgbGreen = pal[row].green; pBmpData->bmp.palette[row].rgbBlue = pal[row].blue; } } png_free(png_ptr, row_pointers[0]); png_free(png_ptr, row_pointers); // clean up after the read, and free any memory allocated png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); // close the file fclose(fp); return RM_OK;}RMbool isJpeg(RMascii *path){ RMuint8 buf[JPG_BYTES_TO_CHECK]; FILE *fp; // Open the prospective JPG file if ((fp = fopen(path, "rb")) == NULL){ return FALSE; } // Read in some of the signature bytes if (fread(buf, 1, JPG_BYTES_TO_CHECK, fp) != JPG_BYTES_TO_CHECK) return FALSE; fclose(fp); return (buf[0] == 0xff && buf[1] == 0xd8);}RMstatus load_jpeg( struct RUA* pRua, RMbitmapdata *pBmpData, RMuint32 *bmpsize){ struct jpeg_decompress_struct cinfo; // decompression params RMfile fp; // source file JSAMPARRAY buffer; // Output buffer RMuint32 row_stride; // physical row width in output buffer struct my_error_mgr jerr; RMuint32 row; RMuint8 bpp; RMbool to32bpp = FALSE; // used if 24bpp to convert to 32bpp RMuint32 databyte, bufbyte; RMuint8 temp; RMuint32 datasize; RMstatus status = RM_OK; RMdrawBuffer bmpbuffer; if((fp = RMOpenFile(pBmpData->path, RM_FILE_OPEN_READ)) == NULL){ fprintf(stderr, "GFXLIB: Cannot open %s\n", pBmpData->path); return RM_ERROR; } // allocate and initialize JPEG decompression object // set up the normal JPEG error routines, then override error_exit. cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; // Establish the setjmp return context for my_error_exit to use. if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); RMCloseFile(fp); return RM_ERROR; } // initialize the JPEG decompression object. jpeg_create_decompress(&cinfo); // specify data source jpeg_stdio_src_rm_file(&cinfo, fp); // read file parameters with jpeg_read_header() jpeg_read_header(&cinfo, TRUE); // scale to 1/2, 1/4 or 1/8 if image does not fit in osd surface. we'll rescale it to fit later on if(cinfo.image_width > g_OSDwidth || cinfo.image_height > g_OSDheight){ cinfo.scale_num = 1; cinfo.scale_denom = calculate_jpeg_denom(cinfo.image_width, cinfo.image_height, g_OSDwidth, g_OSDheight); if(cinfo.scale_denom == 0){ fprintf(stderr, "GFXLIB: NOT ENOUGH DRAM (%lu, %lu bytes) TO ALLOCATE JPEG [%s]\n", (RMuint32)cinfo.image_width, (RMuint32)cinfo.image_height, pBmpData->path); // Release JPEG decompression object jpeg_destroy_decompress(&cinfo); RMCloseFile(fp); return RM_FATALOUTOFMEMORY; } } cinfo.dct_method = JDCT_FASTEST; cinfo.do_fancy_upsampling = FALSE; // Start decompressor jpeg_start_decompress(&cinfo); row_stride = cinfo.output_width * cinfo.output_components; bpp = cinfo.num_components * 8; pBmpData->bmp.uiWidth = cinfo.output_width; pBmpData->bmp.uiHeight = cinfo.output_height; pBmpData->bmp.uiNbBitPerPixel = bpp; // convert to 32 bit data if 24 bit to32bpp = (bpp == 24); if(to32bpp){ datasize = 4 * cinfo.output_width * cinfo.output_height; pBmpData->bmp.uiWidthLenInBytes = 4 * cinfo.output_width; } else{ datasize = row_stride * cinfo.output_height; // adjust to 32bit datasize = datasize + datasize % 4; pBmpData->bmp.uiWidthLenInBytes = row_stride; } if(pBmpData->pBmpAddr == 0){ *bmpsize = datasize; status = AllocateBuffer(&bmpbuffer, datasize, FALSE); if(RMFAILED(status)){ fprintf(stderr, "GFXLIB: NOT ENOUGH DRAM (%lu bytes)TO ALLOCATE JPEG [%s]\n", datasize, pBmpData->path); // Release JPEG decompression object jpeg_destroy_decompress(&cinfo); RMCloseFile(fp); return RM_FATALOUTOFMEMORY; } pBmpData->pBmpAddr = bmpbuffer.baseAddr; pBmpData->bmp.pData = bmpbuffer.pMappedAddr; } pBmpData->bmp.uiDataSize = datasize; RMMemset(pBmpData->bmp.pData, 0xff, pBmpData->bmp.uiDataSize); // Make a one-row-high sample array that will go away when done with image -- handled by libjpeg buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); // copy rows for (row = 0; row < cinfo.output_height; row++){ jpeg_read_scanlines(&cinfo, buffer, 1); if(cinfo.jpeg_color_space != JCS_GRAYSCALE){ // reverse row (gbr -> rgb) for(bufbyte = 0; bufbyte < row_stride; ){ temp = (*buffer)[bufbyte]; (*buffer)[bufbyte] = (*buffer)[bufbyte + 2]; (*buffer)[bufbyte + 2] = temp; bufbyte += 3; } } temp = 0; if(to32bpp){ for(databyte = 0, bufbyte = 0; databyte < 4 * cinfo.output_width; databyte++){ if((databyte + 1) % 4 != 0) pBmpData->bmp.pData[databyte + row * 4 * cinfo.output_width] = (*buffer)[bufbyte++]; } } else{ RMMemcpy(pBmpData->bmp.pData + row * row_stride, *buffer, row_stride); // set alpha to 0xff if background if(pBmpData->isBackground){ for(databyte = 0, bufbyte = 0; databyte < 4 * cinfo.output_width; databyte++){ if((databyte + 1) % 4 == 0) pBmpData->bmp.pData[databyte] = 0xff; } } } } // set LUT if(cinfo.jpeg_color_space == JCS_GRAYSCALE && bpp == 8){ pBmpData->bmp.uiPaletteSize = 1024; for(row = 0; row < 256; row++){ pBmpData->bmp.palette[row].rgbRed = row; pBmpData->bmp.palette[row].rgbGreen = row; pBmpData->bmp.palette[row].rgbBlue = row; } } // Finish decompression jpeg_finish_decompress(&cinfo); // Release JPEG decompression object jpeg_destroy_decompress(&cinfo); RMCloseFile(fp); return RM_OK;}RMstatus load_gif( struct RUA* pRua, RMbitmapdata *pBmpData, RMuint32 *bmpsize){ RMuint32 datasize; RMstatus status; RMuint16 width, height; GifFileType *gif_hdr; RMdrawBuffer bmpbuffer; RMuint16 row, column, i, j; GifRecordType rtype; gif_hdr = DGifOpenFileName(pBmpData->path); if(gif_hdr == NULL) return RM_ERROR; width = gif_hdr->SWidth; height = gif_hdr->SHeight; if(width > g_OSDwidth || height > g_OSDheight){ fprintf(stderr, "GFXLIB: GIF EXCEEDS OSD SURFACE SIZE [%s]\n", pBmpData->path); // clean up after the read, and free any memory allocated DGifCloseFile(gif_hdr); return RM_ERROR; }// printf("width = %ld, height = %ld, bpp = %d, color type = %d, interlaced = %d\n",// width, height, bit_depth, color_type, interlace_type); pBmpData->bmp.uiWidth = width; pBmpData->bmp.uiHeight = height; pBmpData->bmp.uiNbBitPerPixel = (RMuint8) gif_hdr->SColorResolution; pBmpData->bmp.uiWidthLenInBytes = width; datasize = width * height; // adjust to 32bit datasize = datasize + datasize % 4; *bmpsize = datasize; status = AllocateBuffer(&bmpbuffer, datasize, FALSE); if(RMFAILED(status)){ fprintf(stderr, "GFXLIB: NOT ENOUGH DRAM TO ALLOCATE GIF [%s]\n", pBmpData->path); // clean up after the read, and free any memory allocated DGifCloseFile(gif_hdr); return RM_FATALOUTOFMEMORY; } pBmpData->pBmpAddr = bmpbuffer.baseAddr; pBmpData->bmp.pData = bmpbuffer.pMappedAddr; pBmpData->bmp.uiDataSize = datasize; RMMemset(pBmpData->bmp.pData, 0xff, pBmpData->bmp.uiDataSize); // read image record type rtype = UNDEFINED_RECORD_TYPE; DGifGetRecordType(gif_hdr, &rtype); while(rtype != IMAGE_DESC_RECORD_TYPE){ DGifGetRecordType(gif_hdr, &rtype); } // read image data if(DGifGetImageDesc(gif_hdr) == GIF_ERROR){ DGifCloseFile(gif_hdr); return RM_ERROR; } row = gif_hdr->Image.Top; column = gif_hdr->Image.Left; if(gif_hdr->Image.Interlace){ for(i = 0; i < 4; ++i) { for (j = row + interlacedOffset[i]; j < row + height; j+= interlacedJumps[i]){ if(DGifGetLine(gif_hdr, pBmpData->bmp.pData + (j * width), width ) == GIF_ERROR){ DGifCloseFile(gif_hdr); return RM_ERROR; } } } } else{ for(j = 0; j < height; j++) { if(DGifGetLine(gif_hdr, pBmpData->bmp.pData + (j * width), width ) == GIF_ERROR){ DGifCloseFile(gif_hdr); return RM_ERROR; } } } // read LUT if(pBmpData->bmp.uiNbBitPerPixel == 8 && gif_hdr->SColorMap != NULL){ pBmpData->bmp.uiPaletteSize = 1024; for(row = 0; row < 256; row++){ pBmpData->bmp.palette[row].rgbRed = gif_hdr->SColorMap->Colors[row].Red; pBmpData->bmp.palette[row].rgbGreen = gif_hdr->SColorMap->Colors[row].Green; pBmpData->bmp.palette[row].rgbBlue = gif_hdr->SColorMap->Colors[row].Blue;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -