#include #include #include #include #include #include #include "aw_util.h" //#include "uapi_rt_media.h" #include "aw_message_queue.h" argument_t ArgumentMapping[] = { { "-h", "--help", HELP, "Print this help" }, { "-n", "--encode_frame_num", ENCODE_FRAME_NUM, "After encoder n frames, encoder stop" }, { "-f0", "--encode_format0", ENCODE_FORMAT_0, "0:h264 encoder, 1:jpeg_encoder, 2:h265 encoder" }, { "-f1", "--encode_format1", ENCODE_FORMAT_1, "0:h264 encoder, 1:jpeg_encoder, 2:h265 encoder" }, { "-s0", "--srcsize", SRC_SIZE_0, "src_size,can be 1920x1080 or 2160,1080,720,480,288" }, { "-ds0", "--dstsize", DST_SIZE_0, "dst_size,can be 1920x1080 or 2160,1080,720,480,288" }, { "-s1", "--srcsize", SRC_SIZE_1, "src_size,can be 1920x1080 or 2160,1080,720,480,288" }, { "-b0", "--bitrate", BIT_RATE_0, "bitRate:bps" }, { "-b1", "--bitrate", BIT_RATE_1, "bitRate:kbps" }, { "-in", "--inputfile", INPUT_FILE_NAME, "inputfile: It is better to provide absolute paths" }, { "-out", "--outputfile", OUTPUT_FILE_NAME, "outputfile: It is better to provide absolute paths" }, { "-snd", "--second", SUPPORT_SECOND_CHANNEL, "second: support second channel, use to encode sub channel" }, { "-trd", "--third", SUPPORT_THIRD_CHANNEL, "third: support third channel, use to save yuv" }, { "-local", "--local", ENCODE_LOCAL_YUV, "local: only encode local yuv, disable isp" }, { "-pf", "--pxlformat", PIXEL_FORMAT, "pxlformat:set input yuv format NV12 = 0, NV21 = 1, YV12 = 2, YV21 = 3, LBC_25X = 4" }, { "-pf1", "--pxlformat1", PIXEL_FORMAT_1, "pxlformat:set input yuv format NV12 = 0, NV21 = 1, YV12 = 2, YV21 = 3, LBC_25X = 4" }, { "-pf2", "--pxlformat2", PIXEL_FORMAT_2, "pxlformat:set input yuv format NV12 = 0, NV21 = 1, YV12 = 2, YV21 = 3, LBC_25X = 4" }, { "-vn", "--vippnum", USE_VIPP_NUM, "vippnum: set channel 0 use vipp num" }, { "-vn1", "--vippnum1", USE_VIPP_NUM_1, "vippnum: set channel 1 use vipp num" }, { "-vn2", "--vippnum1", USE_VIPP_NUM_2, "vippnum: set channel 2 use vipp num" }, { "-sp", "--sharp", ENABLE_SHARP, "test sharp func" }, { "-js", "--jpgsize", JPG_SIZE, "set jpg size" }, { "-online", "--online_mode", ONLINE_MODE, "online mode" }, { "-sbn", "--share_buf", SHARE_BUF_NUM, "set online share buf num: 1 2" }, { "-roi", "--roi", ENABLE_ROI, "on/off roi" }, { "-fi", "--force_i", ENABLE_FORCE_I_FRAME, "on/off roi" }, { "-ms", "--motion", ENABLE_MOTION_SEARCH, "on/off motion_search" }, { "-osd", "--osd", ENABLE_OSD, "on/off osd" }, { "-orl", "--orl", ENABLE_ORL, "on/off orl" }, { "-rs", "--reset", ENABLE_RESET_SIZE, "on/off reset size" }, { "-gdc", "--gdc", ENABLE_GDC, "on/off gdc" }, { "-cs", "--colorspace", COLOR_SPACE, "set color space" }, { "-ra", "--rotate", ROTATE_ANGEL, "set rotate angle, 0/90/180/270, other angel is not set"}, { "-vb", "--vinbuf", VIN_BUF_NUM, "for channel 1 set vin buf num, should set >= 3"}, { "-crop", "--crop", ENABLE_CROP, "crop test, default coordinate is, x:80, y:64, width:640, high:320"}, { "-gray", "--gray", ENABLE_GRAY, "gray test, enalbe to make stream gray"}, { "-wbyuv", "--wbyuv", ENABLE_WB_YUV_TEST, "setting wbyuv test"}, { "-pir", "--pir", P_INTRA_REFRESH, "P Frame Intra refresh test"}, { "-nr", "--nr", EN_2D_3D_NR_TEST, "2d/3d nr test"}, { "-dfps", "--dstfps", DST_FPS, "dst fps, to venc"}, { "-aiisp", "--aiisp", ENABLE_AIISP, "enable aiisp"}, { "-aiispmode", "--aiispmode", AIISP_MODE, "aiisp mode"}, { "-tdmbuf", "--tdmbuf", TDM_RXBUF_CNT, "tdm rx buf cnt"}, { "-aiispauto", "--aiispauto", AIISP_AUTO_SWITCH, "aiisp auto switch by isp ae param"}, { "-aiispintv", "--aiispintv", AIISP_SWITCH_INTERVAL, "aiisp switch interval"}, { "-aiisp_bin", "--isp_aiisp_bin_path", ISP_AIISP_BIN_PATH, "set isp aiisp bin path when aiisp test"}, { "-day_bin", "--isp_day_bin_path", ISP_DAY_BIN_PATH, "set isp day bin path when aiisp test"}, { "-npu_lut_model", "--npu_lut_model_file_path", NPU_LUT_MODEL_FILE_PATH, "set npu lut model file path when aiisp test"}, { "-npu_model", "--npu_model_file_path", NPU_MODEL_FILE_PATH, "set npu model file path when aiisp test"}, { "-argb_type", "--argb_type", ARGB_TYPE, "set argb_type"}, }; int check_param(demo_video_param *pparam) { if(pparam->c0_src_w <=0 || pparam->c0_src_h <= 0) { pparam->c0_src_w = 2560; pparam->c0_src_h = 1440; } if(pparam->c0_dst_w <=0 || pparam->c0_dst_h <= 0) { pparam->c0_dst_w = pparam->c0_src_w; pparam->c0_dst_h = pparam->c0_src_h; } if(pparam->c0_bitrate <= 0) pparam->c0_bitrate = 1.5*1024*1024; if(pparam->c0_encoder_format < 0) pparam->c0_encoder_format = 0; if(pparam->c1_src_w <=0 || pparam->c1_src_h <= 0) { pparam->c1_src_w = 640; pparam->c1_src_h = 480; } if(pparam->c1_bitrate <= 0) pparam->c1_bitrate = 256*1024; if(pparam->c1_encoder_format < 0) pparam->c1_encoder_format = 0; return 0; } ARGUMENT_T GetArgument(char *name) { int i = 0; int num = sizeof(ArgumentMapping) / sizeof(argument_t); while(i < num) { aw_logv("input_name:%s, i:%d, name:%s, short:%s, argument:%d, num:%d\n", name, i, ArgumentMapping[i].Name, ArgumentMapping[i].Short, ArgumentMapping[i].argument, num); if((0 == strcmp(ArgumentMapping[i].Name, name)) || ((0 == strcmp(ArgumentMapping[i].Short, name)) && (0 != strcmp(ArgumentMapping[i].Short, "--")))) { return ArgumentMapping[i].argument; } i++; } return INVALID; } void PrintDemoUsage(void) { int i = 0; int num = sizeof(ArgumentMapping) / sizeof(argument_t); aw_logd("Usage:"); while(i < num) { aw_logd("%-12s %-32s %s", ArgumentMapping[i].Short, ArgumentMapping[i].Name, ArgumentMapping[i].Description); aw_logd("\n"); i++; } } void ParseArgument(demo_video_param *param, char *argument, char *value) { ARGUMENT_T arg; arg = GetArgument(argument); switch(arg) { case HELP: PrintDemoUsage(); break; case ENABLE_GDC: sscanf(value, "%32u", ¶m->enable_gdc); aw_logd("enable_gdc:%u\n", param->enable_gdc); break; case ENABLE_RESET_SIZE: sscanf(value, "%32u", ¶m->enable_reset_size); aw_logd("enable_reset_size:%u\n", param->enable_reset_size); break; case ENABLE_ORL: sscanf(value, "%32u", ¶m->enable_orl); aw_logd("enable_orl:%u\n", param->enable_orl); break; case ENABLE_OSD: sscanf(value, "%32u", ¶m->enable_osd); aw_logd("enable_osd:%u\n", param->enable_osd); break; case ENABLE_FORCE_I_FRAME: sscanf(value, "%32u", ¶m->enable_force_key_frame); aw_logd("enable_force_key_frame:%u\n", param->enable_force_key_frame); break; case ENABLE_MOTION_SEARCH: sscanf(value, "%32u", ¶m->enable_motion_search); aw_logd("enable_motion_search:%u\n", param->enable_motion_search); break; case ENABLE_ROI: sscanf(value, "%32u", ¶m->enable_roi); aw_logd("enable_roi:%u\n", param->enable_roi); break; case JPG_SIZE: if(strlen(value) > 5) { sscanf(value, "%32ux%32u", ¶m->jpg_width,¶m->jpg_heigh); } else { param->jpg_width = 640; param->jpg_heigh = 368; } aw_logd("jpg_size: %dx%d\n", param->jpg_width, param->jpg_heigh); break; case ENABLE_SHARP: sscanf(value, "%32u", ¶m->enable_sharp); aw_logd("enable_sharp:%u\n", param->enable_sharp); break; case ONLINE_MODE: sscanf(value, "%32u", ¶m->bonline_channel); aw_logd("bonline_channel:%u\n", param->bonline_channel); break; case SHARE_BUF_NUM: sscanf(value, "%32u", ¶m->share_buf_num); aw_logd("share_buf_num:%u\n", param->share_buf_num); break; case USE_VIPP_NUM: sscanf(value, "%32u", ¶m->use_vipp_num); aw_logd("use_vipp_num:%u\n", param->use_vipp_num); break; case USE_VIPP_NUM_1: sscanf(value, "%32u", ¶m->use_vipp_num_1); aw_logd("use_vipp_num_1:%u\n", param->use_vipp_num_1); break; case USE_VIPP_NUM_2: sscanf(value, "%32u", ¶m->use_vipp_num_2); aw_logd("use_vipp_num_2:%u\n", param->use_vipp_num_2); break; case PIXEL_FORMAT: sscanf(value, "%32u", ¶m->pixelformat); aw_logd("pixelformat:%u\n", param->pixelformat); break; case PIXEL_FORMAT_1: sscanf(value, "%32u", ¶m->pixelformat_1); aw_logd("pixelformat_1:%u\n", param->pixelformat_1); break; case PIXEL_FORMAT_2: sscanf(value, "%32u", ¶m->pixelformat_2); aw_logd("pixelformat_2:%u\n", param->pixelformat_2); break; case ENCODE_LOCAL_YUV: sscanf(value, "%32u", ¶m->encode_local_yuv); aw_logd("encode_local_yuv:%u\n", param->encode_local_yuv); break; case SUPPORT_SECOND_CHANNEL: sscanf(value, "%32u", ¶m->en_second_channel); aw_logd("en_second_channel:%u\n", param->en_second_channel); break; case SUPPORT_THIRD_CHANNEL: sscanf(value, "%32u", ¶m->en_third_channel); aw_logd("en_third_channel:%u\n", param->en_third_channel); break; case ENCODE_FRAME_NUM: sscanf(value, "%32u", ¶m->encoder_num); aw_logd("encode:%u frames\n", param->encoder_num); break; case INPUT_FILE_NAME: memset(param->InputFileName, 0, sizeof(param->InputFileName)); sscanf(value, "%127s", param->InputFileName); aw_logd("input file name: %s\n", param->InputFileName); break; case OUTPUT_FILE_NAME: memset(param->OutputFilePath, 0, sizeof(param->OutputFilePath)); sscanf(value, "%127s", param->OutputFilePath); aw_logd("output file path: %s\n", param->OutputFilePath); break; case ENCODE_FORMAT_0: sscanf(value, "%32u", ¶m->c0_encoder_format); aw_logd("c0_encode_format:%u 0:h264,1:jpeg,3:h265\n", param->c0_encoder_format); break; case ENCODE_FORMAT_1: sscanf(value, "%32u", ¶m->c1_encoder_format); aw_logd("c1_encode_format:%u 0:h264,1:jpeg,3:h265\n", param->c1_encoder_format); break; case SRC_SIZE_0: if(strlen(value) > 5) { sscanf(value, "%32ux%32u", ¶m->c0_src_w,¶m->c0_src_h); } else { sscanf(value, "%32u", ¶m->c0_src_size); if(param->c0_src_size == 1080) { param->c0_src_w = 1920; param->c0_src_h = 1080; } else if(param->c0_src_size == 1088) { param->c0_src_w = 1920; param->c0_src_h = 1088; } else if(param->c0_src_size == 720) { param->c0_src_w = 1280; param->c0_src_h = 720; } else if(param->c0_src_size == 480) { param->c0_src_w = 640; param->c0_src_h = 480; } } break; case DST_SIZE_0: if(strlen(value) > 5) { sscanf(value, "%32ux%32u", ¶m->c0_dst_w,¶m->c0_dst_h); } else { sscanf(value, "%32u", ¶m->c0_dst_size); if(param->c0_dst_size == 1080) { param->c0_dst_w = 1920; param->c0_dst_h = 1080; } else if(param->c0_dst_size == 1088) { param->c0_dst_w = 1920; param->c0_dst_h = 1088; } else if(param->c0_dst_size == 720) { param->c0_dst_w = 1280; param->c0_dst_h = 720; } else if(param->c0_dst_size == 480) { param->c0_dst_w = 640; param->c0_dst_h = 480; } } break; case SRC_SIZE_1: if(strlen(value) > 5) { sscanf(value, "%32ux%32u", ¶m->c1_src_w,¶m->c1_src_h); } else { sscanf(value, "%32u", ¶m->c1_src_size); if(param->c1_src_size == 1080) { param->c1_src_w = 1920; param->c1_src_h = 1080; } else if(param->c1_src_size == 1088) { param->c1_src_w = 1920; param->c1_src_h = 1088; } else if(param->c1_src_size == 720) { param->c1_src_w = 1280; param->c1_src_h = 720; } else if(param->c1_src_size == 480) { param->c1_src_w = 640; param->c1_src_h = 480; } } break; case BIT_RATE_0: sscanf(value, "%32u", ¶m->c0_bitrate); aw_logd("c0_bitrate:%u \n", param->c0_bitrate); break; case BIT_RATE_1: sscanf(value, "%32u", ¶m->c1_bitrate); aw_logd("c1_bitrate:%u \n", param->c1_bitrate); break; case COLOR_SPACE: { sscanf(value, "%32u", ¶m->color_space); aw_logd("color space:%u \n", param->color_space); break; } case ROTATE_ANGEL: { sscanf(value, "%32u", ¶m->rotate_angle); aw_logd("rotate angle:%u \n", param->rotate_angle); break; } case VIN_BUF_NUM: { sscanf(value, "%32u", ¶m->vin_buf_num); aw_logd("vin_buf_num:%u \n", param->vin_buf_num); break; } case ENABLE_CROP: { sscanf(value, "%32u", ¶m->enable_crop); aw_logd("enable_crop:%u \n", param->enable_crop); break; } case ENABLE_GRAY: { sscanf(value, "%32u", ¶m->enable_gray); aw_logd("enable_gray:%u \n", param->enable_gray); break; } case ENABLE_WB_YUV_TEST: { sscanf(value, "%32u", ¶m->enable_wbyuv); aw_logd("enable_wbyuv:%u \n", param->enable_wbyuv); break; } case P_INTRA_REFRESH: { sscanf(value, "%32u", ¶m->enable_p_intra_refresh); aw_logd("enable_p_intra_refresh:%u \n", param->enable_p_intra_refresh); break; } case EN_2D_3D_NR_TEST: { sscanf(value, "%32u", ¶m->en_2d_3d_nr); aw_logd("en_2d_3d_nr:%u \n", param->en_2d_3d_nr); break; } case DST_FPS: { sscanf(value, "%32u", ¶m->dst_fps); aw_logd("DST_FPS:%u \n", param->dst_fps); break; } case ENABLE_AIISP: { sscanf(value, "%32u", ¶m->enable_aiisp); aw_logd("enable_aiisp:%u \n", param->enable_aiisp); break; } case ARGB_TYPE: { sscanf(value, "%32u", ¶m->argb_type); aw_logd("argb_type:%u \n", param->argb_type); break; } case AIISP_MODE: { sscanf(value, "%32u", ¶m->aiisp_mode); aw_logd("aiisp_mode:%u \n", param->aiisp_mode); break; } case TDM_RXBUF_CNT: { sscanf(value, "%32u", ¶m->tdm_rxbuf_cnt); aw_logd("tdm_rxbuf_cnt:%u \n", param->tdm_rxbuf_cnt); break; } case AIISP_AUTO_SWITCH: { sscanf(value, "%32u", ¶m->aiisp_auto_switch); aw_logd("aiisp auto switch:%u \n", param->aiisp_auto_switch); break; } case AIISP_SWITCH_INTERVAL: { sscanf(value, "%32u", ¶m->aiisp_switch_interval); aw_logd("aiisp switch interval:%u \n", param->aiisp_switch_interval); break; } case ISP_AIISP_BIN_PATH: memset(param->isp_aiisp_bin_path, 0, sizeof(param->isp_aiisp_bin_path)); strncpy(param->isp_aiisp_bin_path, value, sizeof(param->isp_aiisp_bin_path) - 1); aw_logd("isp aiisp bin path: %s\n", param->isp_aiisp_bin_path); break; case ISP_DAY_BIN_PATH: memset(param->isp_day_bin_path, 0, sizeof(param->isp_day_bin_path)); strncpy(param->isp_day_bin_path, value, sizeof(param->isp_day_bin_path) - 1); aw_logd("isp day bin path: %s\n", param->isp_day_bin_path); break; case NPU_LUT_MODEL_FILE_PATH: memset(param->npu_lut_model_file_path, 0, sizeof(param->npu_lut_model_file_path)); strncpy(param->npu_lut_model_file_path, value, sizeof(param->npu_lut_model_file_path) - 1); aw_logd("npu lut model file path: %s\n", param->npu_lut_model_file_path); break; case NPU_MODEL_FILE_PATH: memset(param->npu_model_file_path, 0, sizeof(param->npu_model_file_path)); strncpy(param->npu_model_file_path, value, sizeof(param->npu_model_file_path) - 1); aw_logd("npu model file path: %s\n", param->npu_model_file_path); break; case INVALID: default: aw_logd("unknowed argument : %s\n", argument); break; } } int rt_is_format422(rt_pixelformat_type pixelformat) { if (pixelformat >= RT_PIXEL_YUV422SP && pixelformat <= RT_PIXEL_VYUY422) return 1; else return 0; } int rt_cal_input_buffer_size(int w, int h, rt_pixelformat_type pixelformat, int read_file) { int buf_size = w*h*3/2; int y_stride = 0; int yc_stride = 0; int pic_width_32align = ALIGN_XXB(32, w); int pic_width_16align = ALIGN_XXB(16, w); int pic_height_16align = ALIGN_XXB(16, h); if (pixelformat == RT_PIXEL_LBC_25X || pixelformat == RT_PIXEL_LBC_2X) { if (pixelformat == RT_PIXEL_LBC_2X) { y_stride = ((LBC_2X_COM_RATIO_EVEN * pic_width_32align * LBC_BIT_DEPTH / 1000 + 511) & (~511)) >> 3; yc_stride = ((LBC_2X_COM_RATIO_ODD * pic_width_32align * LBC_BIT_DEPTH / 500 + 511) & (~511)) >> 3; } else if (pixelformat == RT_PIXEL_LBC_25X) { y_stride = ((LBC_2_5X_COM_RATIO_EVEN * pic_width_32align * LBC_BIT_DEPTH / 1000 + 511) & (~511)) >> 3; yc_stride = ((LBC_2_5X_COM_RATIO_ODD * pic_width_32align * LBC_BIT_DEPTH / 500 + 511) & (~511)) >> 3; } else { y_stride = ((pic_width_32align * LBC_BIT_DEPTH + pic_width_32align / 16 * 2 + 511) & (~511)) >> 3; yc_stride = ((pic_width_32align * LBC_BIT_DEPTH * 2 + pic_width_32align / 16 * 4 + 511) & (~511)) >> 3; } buf_size = (y_stride + yc_stride) * pic_height_16align / 2; //* add more 1KB to fix ve-lbc-error buf_size += LBC_EXT_SIZE; } else if (rt_is_format422(pixelformat)) { if (read_file) { buf_size = w * h * 2; } else { buf_size = pic_width_16align * pic_height_16align * 2; if (pic_width_16align % 64 != 0) buf_size += 64; } } else {//default as yuv420, add other format please additionally add if (read_file) { buf_size = w * h * 3 / 2; } else { buf_size = pic_width_16align * pic_height_16align * 3 / 2; if (pic_width_16align % 64 != 0) buf_size += 64; } } return buf_size; } int bmp_32_to_argb8888(unsigned char* imageData, uint32_t* argbData, struct DIBHeader *dibHeader) { int argb_idx = 0, pixel_num = 0; int width = dibHeader->width, height = dibHeader->height; int rowSize = ((width * dibHeader->bitsPerPixel + 31) / 32) * 4; for (int y = height - 1; y >= 0; y--) { for (int x = 0; x < width; x++) { pixel_num = y * rowSize + x * 4; uint8_t b = imageData[pixel_num]; uint8_t g = imageData[pixel_num + 1]; uint8_t r = imageData[pixel_num + 2]; uint8_t a = imageData[pixel_num + 3]; argbData[argb_idx++] = (a << 24) | (r << 16) | (g << 8) | b; } } } int bmp_24_to_argb8888(unsigned char* imageData, uint32_t* argbData, struct DIBHeader *dibHeader) { int argb_idx = 0, pixel_num = 0; int width = dibHeader->width, height = dibHeader->height; int rowSize = ((width * dibHeader->bitsPerPixel + 31) / 32) * 4; rowSize = ((width * dibHeader->bitsPerPixel + 23) / 24) * 3; for (int y = height - 1; y >= 0; y--) { for (int x = 0; x < width; x++) { pixel_num = y * rowSize + x * 3; uint8_t b = imageData[pixel_num]; uint8_t g = imageData[pixel_num + 1]; uint8_t r = imageData[pixel_num + 2]; argbData[argb_idx++] = (0xFF << 24) | (r << 16) | (g << 8) | b; } } } int bmp_32_to_argb1555(unsigned char* imageData, uint16_t *argbData, struct DIBHeader *dibHeader) { int argb_idx = 0, pixel_num = 0; int width = dibHeader->width, height = dibHeader->height; int rowSize = ((width * dibHeader->bitsPerPixel + 31) / 32) * 4; for (int y = height - 1; y >= 0; y--) { for (int x = 0; x < width; x++) { pixel_num = y * rowSize + x * 4; uint8_t b = imageData[pixel_num] >> 3; uint8_t g = imageData[pixel_num + 1] >> 3; uint8_t r = imageData[pixel_num + 2] >> 3; uint8_t a = (imageData[pixel_num + 3] >= 128) ? 1 : 0; argbData[argb_idx++] = (a << 15) | (r << 10) | (g << 5) | b; } } } int bmp_24_to_argb1555(unsigned char* imageData, uint16_t* argbData, struct DIBHeader *dibHeader, int alpha) { int argb_idx = 0, pixel_num = 0; int width = dibHeader->width, height = dibHeader->height; int rowSize = ((width * dibHeader->bitsPerPixel + 31) / 32) * 4; rowSize = ((width * dibHeader->bitsPerPixel + 23) / 24) * 3; for (int y = height - 1; y >= 0; y--) { for (int x = 0; x < width; x++) { pixel_num = y * rowSize + x * 3; uint8_t b = imageData[pixel_num] >> 3; uint8_t g = imageData[pixel_num + 1] >> 3; uint8_t r = imageData[pixel_num + 2] >> 3; argbData[argb_idx++] = (alpha << 15) | (r << 10) | (g << 5) | b; } } } unsigned char *deal_bmp_data(FILE* fd, VideoInputOSD *pOverlayInfo, int index) { struct BMPHeader bmpHeader; struct DIBHeader dibHeader; int width = pOverlayInfo->item_info[index].widht; int height = pOverlayInfo->item_info[index].height; unsigned char* imageData = NULL; int argb_size = 0; uint32_t* argbData = NULL; fread(&bmpHeader, sizeof(struct BMPHeader), 1, fd); fread(&dibHeader, sizeof(struct DIBHeader), 1, fd); if (dibHeader.bitsPerPixel != 32 && dibHeader.bitsPerPixel != 24) { aw_logw("not support bitcount %d", dibHeader.bitsPerPixel); return NULL; } width = pOverlayInfo->item_info[index].widht = dibHeader.width; height = pOverlayInfo->item_info[index].height = dibHeader.height; if (pOverlayInfo->argb_type == OVERLAY_ARGB8888) argb_size = width * height * 4; else argb_size = width * height * 2; aw_logw("The file is a BMP file. width %d height %d argb_type %d\n", width, height, pOverlayInfo->argb_type); fseek(fd, bmpHeader.dataOffset, SEEK_SET); if (dibHeader.imageSize == 0) { if (dibHeader.bitsPerPixel == 32) dibHeader.imageSize = width * height * 4; else if (dibHeader.bitsPerPixel == 24) dibHeader.imageSize = width * height * 3; } imageData = (unsigned char*)malloc(dibHeader.imageSize); if (!imageData) { aw_loge("malloc imageData failed!"); return NULL; } fread(imageData, dibHeader.imageSize, 1, fd); aw_logd("fileSize %d dataOffset %d", bmpHeader.fileSize, bmpHeader.dataOffset); aw_logd("argb_size %d imageSize %d width %d height %d\n", argb_size,\ dibHeader.imageSize, width, height); aw_logd("bitsPerPixel %d compression %d\n", dibHeader.bitsPerPixel, dibHeader.compression); argbData = (unsigned char *)malloc(argb_size); if (!argbData) { aw_loge("malloc argbData failed!"); return NULL; } if (dibHeader.bitsPerPixel == 32) { if (pOverlayInfo->argb_type == OVERLAY_ARGB8888) bmp_32_to_argb8888(imageData, argbData, &dibHeader); else if (pOverlayInfo->argb_type == OVERLAY_ARGB1555) { uint16_t *argbData_1555 = (uint16_t *)argbData; bmp_32_to_argb1555(imageData, argbData_1555, &dibHeader); } else aw_loge("not support %d", pOverlayInfo->argb_type); } else if (dibHeader.bitsPerPixel == 24) { if (pOverlayInfo->argb_type == OVERLAY_ARGB8888) bmp_24_to_argb8888(imageData, argbData, &dibHeader); else if (pOverlayInfo->argb_type == OVERLAY_ARGB1555) { uint16_t *argbData_1555 = (uint16_t *)argbData; bmp_24_to_argb1555(imageData, argbData_1555, &dibHeader, 1); } else aw_loge("not support %d", pOverlayInfo->argb_type); } else { aw_logw("Unsupported image data format\n"); } #if 0//for debug save argb data. FILE *argbFile = fopen("output.argb", "wb"); if (!argbFile) { aw_loge("Failed to create output file\n"); return -1; } fwrite(argbData, argb_size, 1, argbFile); fclose(argbFile); #endif free(imageData); return (unsigned char *)argbData; }