📄 bitmaps.c
字号:
/***************************************** Copyright © 2001-2003 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential*****************************************/#include "sample_os.h"#define ALLOW_OS_CODE 1#include "common.h"#include "bitmaps.h" #include "rmmemfile.h"#include "rminputstream.h"#if ((EM86XX_CHIP==EM86XX_CHIPID_TANGO15)&&(EM86XX_MODE==EM86XX_MODEID_STANDALONE))#include "rua_memory.h"#endif #define JPEG_MAX_LINES_PER_IMCU 32static void create_gray_fields_420(RMuint32 width, RMuint32 height, RMuint8 *Y_plane, RMuint8 *UV_plane){ RMuint32 i, j, k, x, y; RMuint8 luma; /* fill chroma buffer with 0x80 0x80 */ for (y = 0; y < height; y+=2) { for (x = 0; x < width; x+=2) { *UV_plane++ = 0x80; *UV_plane++ = 0x80; } } /* slow but precise: fill luma buffer with zig-zag pattern from 0 to 255 */ /* top 16th of image: 0 .. 15 */ /* 2nd 16th of image: 31 .. 16 */ /* 3rd 16th of image: 32 .. 47 etc. */ /* bot 16th of image: 255 .. 240 */ for (y = 0; y < height; y++) { j = y * 16 / height; for (x = 0; x < width; x++) { i = x * 16 / width; k = (j & 1) ? (15 - i) : i; luma = j * 16 + k; *Y_plane++ = luma; } }}static void create_gray_fields_RGB(RMuint32 width, RMuint32 height, RMuint8 *plane, RMuint8 alpha){ RMuint32 i, j, k, x, y; RMuint32 pixel; /* slow but precise: fill pixel buffer with gray zig-zag pattern from 0 to 255 */ /* top 16th of image: 0 .. 15 */ /* 2nd 16th of image: 31 .. 16 */ /* 3rd 16th of image: 32 .. 47 etc. */ /* bot 16th of image: 255 .. 240 */ for (y = 0; y < height; y++) { j = y * 16 / height; for (x = 0; x < width; x++) { i = x * 16 / width; k = (j & 1) ? (15 - i) : i; pixel = j * 16 + k; *plane++ = pixel; *plane++ = pixel; *plane++ = pixel; *plane++ = alpha; } }}static void create_burst_bit2_fields_RGB(RMuint32 width, RMuint32 height, RMuint8 *plane, RMuint8 alpha){ RMuint32 x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { *plane++ = (x & 1) ? 0 : 0xFB; *plane++ = (x & 1) ? 0 : 0xFF; *plane++ = (x & 1) ? 0 : 0xFF; *plane++ = alpha; } }}static void create_burst_bit2_1_fields_RGB(RMuint32 width, RMuint32 height, RMuint8 *plane, RMuint8 alpha){ RMuint32 x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { *plane++ = (x & 1) ? 0x04 : 0xFF; *plane++ = (x & 1) ? 0x00 : 0xFF; *plane++ = (x & 1) ? 0x00 : 0xFF; *plane++ = alpha; } }}static void rgb_to_yuv(RMuint8 r, RMuint8 g, RMuint8 b, RMuint8 *y, RMuint8 *cb, RMuint8 *cr){ *y = r * 77 + g * 150 + b * 29; *cb = 128 + r * -43 + g * -85 + b * 128; *cr = 128 + r * 128 + g * 107 + b * 21;}static void create_grayrgb_fields_420(RMuint32 width, RMuint32 height, RMuint8 *Y_plane, RMuint8 *UV_plane){ RMuint32 i, j, k, x, y, c; RMuint8 pixel, luma, cb, cr; /* slow but precise: fill luma buffer with zig-zag pattern from 0 to 255 */ /* top 16th of image: 0 .. 15 */ /* 2nd 16th of image: 31 .. 16 */ /* 3rd 16th of image: 32 .. 47 etc. */ /* bot 16th of image: 255 .. 240 */ for (y = 0; y < height; y++) { j = y * 16 / height; c = (y * 64 / height) & 0x03; for (x = 0; x < width; x++) { i = x * 16 / width; k = (j & 1) ? (15 - i) : i; pixel = j * 16 + k; rgb_to_yuv( ((c == 0) | (c == 1)) ? pixel : 0, ((c == 0) | (c == 2)) ? pixel : 0, ((c == 0) | (c == 3)) ? pixel : 0, &luma, &cb, &cr); *Y_plane++ = luma; if (((x & 1) == 0) && ((y & 1) == 0)) { *UV_plane++ = cb; *UV_plane++ = cr; } } }}static void create_grayrgb_fields_RGB(RMuint32 width, RMuint32 height, RMuint8 *plane, RMuint8 alpha){ RMuint32 i, j, k, x, y, c; RMuint32 pixel; /* slow but precise: fill pixel buffer with gray zig-zag pattern from 0 to 255 */ /* top 16th of image: 0 .. 15 */ /* 2nd 16th of image: 31 .. 16 */ /* 3rd 16th of image: 32 .. 47 etc. */ /* bot 16th of image: 255 .. 240 */ for (y = 0; y < height; y++) { j = y * 16 / height; c = (y * 64 / height) & 0x03; for (x = 0; x < width; x++) { i = x * 16 / width; k = (j & 1) ? (15 - i) : i; pixel = j * 16 + k; *plane++ = ((c == 0) | (c == 3)) ? pixel : 0; // blue *plane++ = ((c == 0) | (c == 2)) ? pixel : 0; // green *plane++ = ((c == 0) | (c == 1)) ? pixel : 0; // red *plane++ = alpha; // alpha } }}static RMstatus open_bmp_file(struct RMbmpInfo *bmp_info, struct DCCOSDProfile *profile ){ RMuint16 compression; RMuint32 p = 0, used_colors, read_size; RMstatus err; RMuint8 header_buf[54]; err = RMReadFile(bmp_info->fp, header_buf, 54, &read_size); /*read the header */ if(RMFAILED(err)){ RMDBGLOG((ENABLE, "Failed to read the bmp header\n")); return RM_ERROR; } p = 18; bmp_info->width = RMleBufToUint32(header_buf + p); p += 4; bmp_info->height = RMleBufToUint32(header_buf + p); p += 4; p += 2; bmp_info->bpp = RMleBufToUint16(header_buf + p); p += 2; compression = RMleBufToUint32(header_buf + p); p += 2; p += 14; used_colors = RMleBufToUint32(header_buf + p); p += 4; if(compression != 0){ RMDBGLOG((ENABLE, "BMP error: sub format not yet supported\n")); return RM_ERROR; } /* palette size */ if (bmp_info->bpp < 16) bmp_info->palette_size = (used_colors == 0) ? (RMuint32)(1<<bmp_info->bpp) : used_colors; else bmp_info->palette_size = 0; /* init profile structure */ profile->ColorSpace = EMhwlibColorSpace_RGB_0_255; profile->SamplingMode = EMhwlibSamplingMode_444; profile->PixelAspectRatio.X = 1; profile->PixelAspectRatio.Y = 1; profile->Width = bmp_info->width; profile->Height = bmp_info->height; switch(bmp_info->bpp){ case 1: profile->ColorMode = EMhwlibColorMode_LUT_1BPP; profile->ColorFormat = EMhwlibColorFormat_32BPP; profile->Width += (8-(bmp_info->width & 7))&7; /*make the image byte-aligned*/ break; case 4: profile->ColorMode = EMhwlibColorMode_LUT_4BPP; profile->ColorFormat = EMhwlibColorFormat_32BPP; profile->Width += bmp_info->width & 1; /*make the image byte-aligned*/ break; case 8: profile->ColorMode = EMhwlibColorMode_LUT_8BPP; profile->ColorFormat = EMhwlibColorFormat_32BPP; break; case 16: profile->ColorFormat = EMhwlibColorFormat_16BPP_1555; profile->ColorMode = EMhwlibColorMode_TrueColor; break; case 24: profile->ColorFormat = EMhwlibColorFormat_32BPP; profile->ColorMode = EMhwlibColorMode_TrueColor; break; case 32: profile->ColorFormat = EMhwlibColorFormat_32BPP; profile->ColorMode = EMhwlibColorMode_TrueColor; break; default: RMDBGLOG((ENABLE, "Invalid bitmap format: %ld bpp, has to be either 1, 4, 8, 16, 24 bpp!\n", bmp_info->bpp)); return RM_ERROR; } return RM_OK;}static RMstatus bmp_get_palette(RMuint32 *palette, struct RMbmpInfo *bmp_info){ RMuint32 alpha_hi, read_size; RMstatus err; RMDBGLOG((ENABLE, "PALETTE SIZE is %ld\n", bmp_info->palette_size)); err = RMSeekFile(bmp_info->fp, 54, RM_FILE_SEEK_START); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "RMSeekFile failed\n")); return RM_ERROR; } if (bmp_info->palette_size) { RMuint32 i; if (palette == NULL) { return RM_ERROR; } err = RMReadFile(bmp_info->fp, (RMuint8*)palette, 4*bmp_info->palette_size, &read_size); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "RMReadFile failed\n")); return RM_ERROR; } alpha_hi = (bmp_info->alpha<<24); for (i = 0; i < bmp_info->palette_size; i++) { palette[i] = (palette[i] & 0x00ffffff) | alpha_hi; } } return RM_OK;}static RMstatus bmp_to_raw(RMuint8 *luma, struct RMbmpInfo *bmp_info){ RMuint32 bpl, extrabytes, line, col, offs = 0, read_size; RMuint32 *luma32; RMstatus err; RMuint8 *line_buf; /*replace this by a seek */ err = RMSeekFile(bmp_info->fp, 54 + bmp_info->palette_size*4, RM_FILE_SEEK_START); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "RMSeekFile failed\n")); return RM_ERROR; } bpl = (bmp_info->width * bmp_info->bpp + 7) / 8; /* bytes per line */ extrabytes = (4 - ( bpl & 3)) & 3; /* bytes to go after each line until a 4byte boundary */ switch(bmp_info->bpp){ case 1: case 4: case 8: case 16: case 32: for (line = 0; line < bmp_info->height; line++) { offs = (bmp_info->height - line - 1) * bpl; err = RMReadFile(bmp_info->fp, luma + offs, bpl, &read_size); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "RMReadFile failed\n")); return RM_ERROR; } if(extrabytes){ err = RMSeekFile(bmp_info->fp, extrabytes, RM_FILE_SEEK_CURRENT); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "RMSeekFile failed\n")); return RM_ERROR; } } } break; case 24: luma32 = (RMuint32*) luma; line_buf = RMMalloc(bmp_info->width*4); for (line = 0; line < bmp_info->height; line++) { err = RMReadFile(bmp_info->fp, line_buf, bmp_info->width*3, &read_size); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "RMReadFile failed\n")); return RM_ERROR; } /* insert the unused bytes (!). Must be done from end to beginning to not overwrite pixels*/ for (col = 0; col < bmp_info->width; col++){ line_buf[4*(bmp_info->width-col)-1] = bmp_info->alpha; line_buf[4*(bmp_info->width-col)-2] = line_buf[3*(bmp_info->width-col)-1]; line_buf[4*(bmp_info->width-col)-3] = line_buf[3*(bmp_info->width-col)-2]; line_buf[4*(bmp_info->width-col)-4] = line_buf[3*(bmp_info->width-col)-3]; } offs = (bmp_info->height - line - 1) * 4 *(bmp_info->width); RMMemcpy(luma + offs, line_buf, bmp_info->width*4); if(extrabytes){ err = RMSeekFile(bmp_info->fp, extrabytes, RM_FILE_SEEK_CURRENT); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "RMSeekFile failed\n")); return RM_ERROR; } } } RMFree(line_buf); break; default: break; } return RM_OK;}/* this is the callback used by libpng to read data */static void png_read_data_rm_file(png_structp png_ptr, png_bytep buf, png_size_t size){ RMfile fp = (RMfile)png_ptr->io_ptr; RMuint32 read_size; RMstatus err; do{ err = RMReadFile(fp, (RMuint8*)buf, (RMuint32)size, &read_size); size -= read_size; }while (RMSUCCEEDED(err) && (size)); if(RMFAILED(err)) png_error(png_ptr, "Read Error!");}/* this is the callback used by libungif to read data */static int gif_read_data_rm_file(GifFileType *gif_ptr, GifByteType *buf, int size){ RMfile fp = (RMfile)gif_ptr->UserData; RMuint32 read_size; RMstatus err; err = RMReadFile(fp, (RMuint8*)buf, (RMuint32)size, &read_size); if (RMFAILED(err)) return -1; return (int)read_size;}static RMstatus open_png_file(struct RMpngInfo *png_info, struct DCCOSDProfile *profile ){ png_uint_32 width, height; int bit_depth, color_type, interlace_type; png_info->gray_levels = 0; png_info->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_info->png_ptr == NULL){ return RM_ERROR; } png_info->info_ptr = png_create_info_struct(png_info->png_ptr); if (png_info->info_ptr == NULL){ goto cleanup; } if (setjmp(png_jmpbuf(png_info->png_ptr))){ goto cleanup; } png_set_read_fn(png_info->png_ptr, (png_voidp)png_info->fp, png_read_data_rm_file); png_read_info(png_info->png_ptr, png_info->info_ptr); /*swap rgb */ png_set_bgr(png_info->png_ptr); png_get_IHDR(png_info->png_ptr, png_info->info_ptr, &width , &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); RMDBGLOG((ENABLE, "Width is %ld, Height is %ld, bit_depth %ld, color_type %ld\n", width, height, bit_depth, color_type)); profile->ColorSpace = EMhwlibColorSpace_RGB_0_255; profile->SamplingMode = EMhwlibSamplingMode_444; profile->ColorFormat = EMhwlibColorFormat_32BPP; profile->PixelAspectRatio.X = 1; profile->PixelAspectRatio.Y = 1; profile->Width = png_info->width = width; profile->Height = png_info->height = height; /* we don't handle 16 bits per channel, strip to 8 */ if (bit_depth == 16){ png_set_strip_16(png_info->png_ptr); bit_depth = 8; } switch(color_type){ case PNG_COLOR_TYPE_RGB: /* use the png transparency info for creating an alpha channel */ if (png_get_valid(png_info->png_ptr, png_info->info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_info->png_ptr); } /* or simply set the user's desired alpha */ else{ png_set_filler(png_info->png_ptr, png_info->alpha, PNG_FILLER_AFTER); } /* no break */ case PNG_COLOR_TYPE_RGBA: profile->ColorMode = EMhwlibColorMode_TrueColor; if(bit_depth != 8){ } break; case PNG_COLOR_TYPE_GRAY: png_info->gray_levels = 1<<bit_depth; /*no break */ case PNG_COLOR_TYPE_PALETTE: switch(bit_depth){ case 8: profile->ColorMode = EMhwlibColorMode_LUT_8BPP; break; case 4: profile->ColorMode = EMhwlibColorMode_LUT_4BPP; break; case 2: profile->ColorMode = EMhwlibColorMode_LUT_2BPP; break; case 1: profile->ColorMode = EMhwlibColorMode_LUT_1BPP; break; default: goto cleanup; } break; default: goto cleanup; } /* this is possibly not needed...*/ png_read_update_info(png_info->png_ptr, png_info->info_ptr); return RM_OK; cleanup: png_destroy_read_struct(&(png_info->png_ptr), &(png_info->info_ptr), (png_infopp)NULL); return RM_ERROR; }static RMstatus png_to_raw(RMuint8 *luma, struct RMpngInfo *png_info){ RMuint32 row; png_bytep row_pointers[png_info->height]; RMuint8* row_start; row_start = luma; for (row = 0; row < png_info->height; row++){ row_pointers[row] = row_start; row_start += png_get_rowbytes(png_info->png_ptr,png_info->info_ptr); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -