#include <loadjpeg.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
extern "C" {
#include <mjpegdec.h>
}
#define USE_MMAP
Image loadJpegFile(const char *filename)
{
// printf("loading file\n");
int data_size = 0;
FILE *f = fopen(filename, "r");
fseek(f, 0, SEEK_END);
data_size = ftell(f);
fseek(f, 0, SEEK_SET);
printf("size is %i bytes\n", data_size);
fclose(f);
assert( data_size < 2000000 );
#ifdef USE_MMAP
int fd = open(filename, O_RDONLY);
uint8_t *data = (uint8_t *)mmap(0, data_size, PROT_READ, MAP_SHARED, fd, 0);
#else
uint8_t *data = (uint8_t *)malloc(data_size);
if ( fread(data, 1, data_size, f) != data_size )
printf("error reading it all in\n");
#endif
// printf("read in %i bytes of jpeg file\n", data_size);
int i;
for(i=0;i<256;i++)
ff_cropTbl[i + MAX_NEG_CROP] = i;
for(i=0;i<MAX_NEG_CROP;i++) {
ff_cropTbl[i] = 0;
ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
}
AVCodecContext *avctx = (AVCodecContext*)malloc(sizeof(AVCodecContext));
memset(avctx, 0, sizeof(AVCodecContext));
MJpegDecodeContext *s = (MJpegDecodeContext*)malloc(sizeof(MJpegDecodeContext));
memset(s, 0, sizeof(MJpegDecodeContext));
avctx->priv_data = s;
ff_mjpeg_decode_init(avctx);
// printf("init\n");
ff_mjpeg_decode_frame(avctx, 0, 0, data, data_size);
// printf("decoded\n");
/*
ff_mjpeg_decode_end(avctx);
free(data);
fseek(f, 0, SEEK_SET);
data = (uint8_t *)malloc(data_size);
if ( fread(data, 1, data_size, f) != data_size )
printf("error reading it all in\n");
//memset(s, 0, sizeof(MJpegDecodeContext));
//memset(avctx, 0, sizeof(AVCodecContext));
ff_mjpeg_decode_init(avctx);
printf("read in %i bytes of jpeg file\n", data_size);
ff_mjpeg_decode_frame(avctx, 0, 0, data, data_size);
printf("decoded\n");
*/
assert(s->width < 4096);
assert(s->height < 4096);
AVPicture YuvPic = *(AVPicture*)&s->picture;
AVPicture pic;
assert( (s->width*s->height*4) < 5000000 );
pic.data[0] = (unsigned char *)malloc(s->width*s->height*4);
pic.linesize[0] = s->width*4;
pic.width = s->width;
pic.height = s->height;
if ( avctx->pix_fmt == PIX_FMT_YUVJ444P )
yuvj444p_to_rgb32(&pic, &YuvPic, s->width, s->height);
else if ( avctx->pix_fmt == PIX_FMT_YUVJ420P )
yuvj420p_to_rgb32(&pic, &YuvPic, s->width, s->height);
else
printf("unknown color format\n");
// printf("color converted\n");
ff_mjpeg_decode_end(avctx);
free(s);
free(avctx);
#ifdef USE_MMAP
munmap(data, data_size);
close(fd);
#else
free(data);
#endif
free(YuvPic.data[0]);
free(YuvPic.data[1]);
free(YuvPic.data[2]);
Image img(pic.width, pic.height, pic.data[0], Format_ARGB_8888, pic.linesize[0]);
return img;
}