uint8_t * ReadToPNGPicture(uint8_t * buf, size_t buf_len, size_t * buf_out, int bit_depth, int * returnValue) { mem_encode mempng; BPGDecoderContext *img; img = bpg_decoder_open(); if (bpg_decoder_decode(img, buf, buf_len) < 0) { fprintf(stderr, "Could not decode image\n"); return 0; } *returnValue = png_save(img, &mempng, bit_depth); bpg_decoder_close(img); buf_out = mempng.size; return mempng.buffer; }
int main(int argc, char **argv) { FILE *f; BPGDecoderContext *img; uint8_t *buf; int buf_len, bit_depth, c, show_info; const char *outfilename, *filename, *p; outfilename = "out.png"; bit_depth = 8; show_info = 0; for(;;) { c = getopt(argc, argv, "ho:b:i"); if (c == -1) break; switch(c) { case 'h': show_help: help(); break; case 'o': outfilename = optarg; break; case 'b': bit_depth = atoi(optarg); break; case 'i': show_info = 1; break; default: exit(1); } } if (optind >= argc) goto show_help; filename = argv[optind++]; if (show_info) { bpg_show_info(filename, 1); return 0; } f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "Could not open %s\n", filename); exit(1); } fseek(f, 0, SEEK_END); buf_len = ftell(f); fseek(f, 0, SEEK_SET); buf = malloc(buf_len); if (fread(buf, 1, buf_len, f) != buf_len) { fprintf(stderr, "Error while reading file\n"); exit(1); } fclose(f); img = bpg_decoder_open(); if (bpg_decoder_decode(img, buf, buf_len) < 0) { fprintf(stderr, "Could not decode image\n"); exit(1); } free(buf); #ifdef USE_PNG p = strrchr(outfilename, '.'); if (p) p++; if (p && strcasecmp(p, "ppm") != 0) { png_save(img, outfilename, bit_depth); } else #endif { ppm_save(img, outfilename); } bpg_decoder_close(img); return 0; }
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------ DLLFORMATBPG_API int BPG_GetPictureRGBA(uint8_t * buf, size_t buf_len, uint8_t * data, size_t data_len, int & width, int & height, bool flip) { BPGDecoderContext *img; BPGImageInfo img_info_s; int returnValue = 0; if (buf_len > 0 && buf != nullptr) { img = bpg_decoder_open(); if (bpg_decoder_decode(img, buf, buf_len) >= 0) { bpg_decoder_get_info(img, &img_info_s); width = img_info_s.width; height = img_info_s.height; int pictureSize = width * height * 4; if (data != nullptr && pictureSize == data_len) { BPGDecoderOutputFormat out_fmt; int strideLine = 4 * width; //if (img_info_s.has_alpha) out_fmt = BPG_OUTPUT_FORMAT_RGBA32; /* else { strideLine = ((((width * 24) + 31) & ~31) >> 3); out_fmt = BPG_OUTPUT_FORMAT_RGB24; }*/ bpg_decoder_start(img, out_fmt); //int bpp = (3 + img_info_s.has_alpha) * (img_info_s.bit_depth / 8); //Calcul stride uint8_t * rgb_line = new uint8_t[strideLine]; for (auto y = 0; y < height; y++) { int returnValue = bpg_decoder_get_line(img, rgb_line); if (!flip) { memcpy(data + (strideLine * y), rgb_line, strideLine); } else { #pragma omp parallel for (auto x = 0; x < width; x++) { int position = (((flip ? height - y - 1 : y)) * 4 * width) + x * 4; memcpy(data + position, rgb_line + (x * 4), 4 * sizeof(uint8_t)); } } } delete[] rgb_line; } else returnValue = -1; } else returnValue = -1; bpg_decoder_close(img); } else returnValue = -1; return returnValue; }
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------ DLLFORMATBPG_API int BPG_GetPictureBGRA(uint8_t * buf, size_t buf_len, uint8_t * data, size_t data_len, int & width, int & height, bool flip) { BPGDecoderContext *img; BPGImageInfo img_info_s; int returnValue = 0; printf("BPG_GetPictureBGRA \n"); if (buf_len > 0 && buf != nullptr) { printf("bpg_decoder_open \n"); img = bpg_decoder_open(); printf("bpg_decoder_decode \n"); if (bpg_decoder_decode(img, buf, buf_len) >= 0) { printf("bpg_decoder_get_info \n"); bpg_decoder_get_info(img, &img_info_s); width = img_info_s.width; height = img_info_s.height; printf("bpg_decoder_get_info %d %d \n", width, height); int pictureSize = width * height * 4; if (data != nullptr && pictureSize == data_len) { BPGDecoderOutputFormat out_fmt; int strideLine = 4 * width; out_fmt = BPG_OUTPUT_FORMAT_RGBA32; bpg_decoder_start(img, out_fmt); //int bpp = (3 + img_info_s.has_alpha) * (img_info_s.bit_depth / 8); //Calcul stride uint8_t * rgb_line = new uint8_t[strideLine]; for (auto y = 0; y < height; y++) { int returnValue = bpg_decoder_get_line(img, rgb_line); #pragma omp parallel for (auto x = 0; x < width; x++) { int position = (((flip ? height - y - 1 : y)) * 4 * width) + x * 4; data[position + 2] = rgb_line[x * 4]; data[position + 1] = rgb_line[x * 4 + 1]; data[position] = rgb_line[x * 4 + 2]; data[position + 3] = rgb_line[x * 4 + 3]; } } delete[] rgb_line; } else returnValue = -1; } else returnValue = -1; bpg_decoder_close(img); } else returnValue = -1; return returnValue; }
/* * This function must be fed with a complete compressed frame. */ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_block; picture_t *p_pic = 0; BPGImageInfo img_info; if( !pp_block || !*pp_block ) return NULL; p_block = *pp_block; *pp_block = NULL; if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) goto error; /* Decode picture */ if( bpg_decoder_decode( p_sys->p_bpg, p_block->p_buffer, p_block->i_buffer ) < 0 ) { msg_Err( p_dec, "Could not decode block" ); goto error; } if( bpg_decoder_get_info( p_sys->p_bpg, &img_info ) ) { msg_Err( p_dec, "Could not get info for decoder" ); goto error; } if( bpg_decoder_start( p_sys->p_bpg, BPG_OUTPUT_FORMAT_RGB24 ) ) { msg_Err( p_dec, "Could not start decoder" ); goto error; } /* Set output properties */ p_dec->fmt_out.i_codec = VLC_CODEC_RGB24; p_dec->fmt_out.video.i_visible_width = p_dec->fmt_out.video.i_width = img_info.width; p_dec->fmt_out.video.i_visible_height = p_dec->fmt_out.video.i_height = img_info.height; p_dec->fmt_out.video.i_sar_num = 1; p_dec->fmt_out.video.i_sar_den = 1; p_dec->fmt_out.video.i_rmask = 0x000000ff; p_dec->fmt_out.video.i_gmask = 0x0000ff00; p_dec->fmt_out.video.i_bmask = 0x00ff0000; /* Get a new picture */ p_pic = decoder_NewPicture( p_dec ); if( !p_pic ) { goto error; } const int img_height = img_info.height; for (int i = 0; i < img_height; i++) { if( bpg_decoder_get_line( p_sys->p_bpg, p_pic->p->p_pixels + p_pic->p->i_pitch * i ) < 0 ) { msg_Err( p_dec, "Could not decode line" ); goto error; } } p_pic->date = p_block->i_pts > VLC_TS_INVALID ? p_block->i_pts : p_block->i_dts; block_Release( p_block ); return p_pic; error: block_Release( p_block ); return NULL; }
Frame *bpg_load(FILE *f, int *pframe_count, int *ploop_count) { BPGDecoderContext *s; BPGImageInfo bi_s, *bi = &bi_s; uint8_t *buf; int len, y; SDL_Surface *img; Frame *frames; uint32_t rmask, gmask, bmask, amask; int frame_count, i, delay_num, delay_den; fseek(f, 0, SEEK_END); len = ftell(f); fseek(f, 0, SEEK_SET); if (len < 0) return NULL; buf = malloc(len); if (!buf) return NULL; if (fread(buf, 1, len, f) != len) return NULL; frames = NULL; frame_count = 0; s = bpg_decoder_open(); if (bpg_decoder_decode(s, buf, len) < 0) goto fail; bpg_decoder_get_info(s, bi); #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif for(;;) { if (bpg_decoder_start(s, BPG_OUTPUT_FORMAT_RGBA32) < 0) break; bpg_decoder_get_frame_duration(s, &delay_num, &delay_den); frames = realloc(frames, sizeof(frames[0]) * (frame_count + 1)); img = SDL_CreateRGBSurface(SDL_HWSURFACE, bi->width, bi->height, 32, rmask, gmask, bmask, amask); if (!img) goto fail; SDL_LockSurface(img); for(y = 0; y < bi->height; y++) { bpg_decoder_get_line(s, (uint8_t *)img->pixels + y * img->pitch); } SDL_UnlockSurface(img); frames[frame_count].img = img; frames[frame_count].delay = (delay_num * 1000) / delay_den; frame_count++; } bpg_decoder_close(s); *pframe_count = frame_count; *ploop_count = bi->loop_count; return frames; fail: bpg_decoder_close(s); for(i = 0; i < frame_count; i++) { SDL_FreeSurface(frames[i].img); } free(frames); *pframe_count = 0; return NULL; }