static void ppm_save(BPGDecoderContext *img, const char *filename) { BPGImageInfo img_info_s, *img_info = &img_info_s; FILE *f; int w, h, y; uint8_t *rgb_line; bpg_decoder_get_info(img, img_info); w = img_info->width; h = img_info->height; rgb_line = malloc(3 * w); f = fopen(filename,"wb"); if (!f) { fprintf(stderr, "%s: I/O error\n", filename); exit(1); } fprintf(f, "P6\n%d %d\n%d\n", w, h, 255); bpg_decoder_start(img, BPG_OUTPUT_FORMAT_RGB24); for (y = 0; y < h; y++) { bpg_decoder_get_line(img, rgb_line); fwrite(rgb_line, 1, w * 3, f); } fclose(f); free(rgb_line); }
static int png_save(BPGDecoderContext *img, mem_encode * mempng, int bit_depth) { BPGImageInfo img_info_s, *img_info = &img_info_s; FILE *f; png_structp png_ptr; png_infop info_ptr; png_bytep row_pointer; int y, color_type, bpp; BPGDecoderOutputFormat out_fmt; mempng->buffer = 0; mempng->size = 0; if (bit_depth != 8 && bit_depth != 16) { fprintf(stderr, "Only bit_depth = 8 or 16 are supported for PNG output\n"); return -1; } bpg_decoder_get_info(img, img_info); png_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, NULL, /* error */ NULL, /* warning */ NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); png_set_write_fn(png_ptr, (png_voidp)mempng, &png_write_data_buffer, NULL); if (setjmp(png_jmpbuf(png_ptr)) != 0) { fprintf(stderr, "PNG write error\n"); return -1; } if (img_info->has_alpha) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else color_type = PNG_COLOR_TYPE_RGB; png_set_IHDR(png_ptr, info_ptr, img_info->width, img_info->height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); #if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ if (bit_depth == 16) { png_set_swap(png_ptr); } #endif if (bit_depth == 16) { if (img_info->has_alpha) out_fmt = BPG_OUTPUT_FORMAT_RGBA64; else out_fmt = BPG_OUTPUT_FORMAT_RGB48; } else { if (img_info->has_alpha) out_fmt = BPG_OUTPUT_FORMAT_RGBA32; else out_fmt = BPG_OUTPUT_FORMAT_RGB24; } bpg_decoder_start(img, out_fmt); bpp = (3 + img_info->has_alpha) * (bit_depth / 8); row_pointer = (png_bytep)png_malloc(png_ptr, img_info->width * bpp); for (y = 0; y < img_info->height; y++) { bpg_decoder_get_line(img, row_pointer); png_write_row(png_ptr, row_pointer); } png_free(png_ptr, row_pointer); png_write_end(png_ptr, NULL); png_destroy_write_struct(&png_ptr, &info_ptr); 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; }