-
Notifications
You must be signed in to change notification settings - Fork 2
/
loadjpg.c
100 lines (74 loc) · 2.32 KB
/
loadjpg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <jpeglib.h>
#include "bcm_host.h"
#include "image.h"
bool loadJPG(const char *f_name, Image *image) {
int rc, i, j;
// ------------------------------------------------------------------- SETUP
// Variables for the source jpg
struct stat file_info;
unsigned long jpg_size;
unsigned char *jpg_buffer;
// Variables for the decompressor itself
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
// Variables for the output buffer, and how long each row is
unsigned long bmp_size;
unsigned char *bmp_buffer;
int row_stride, width, height, pixel_size;
rc = stat(f_name, &file_info);
if (rc) {
// syslog(LOG_ERR, "FAILED to stat source jpg");
return false;
}
jpg_size = file_info.st_size;
jpg_buffer = (unsigned char*) malloc(jpg_size + 100);
int fd = open(f_name, O_RDONLY);
i = 0;
while (i < jpg_size) {
rc = read(fd, jpg_buffer + i, jpg_size - i);
// syslog(LOG_INFO, "Input: Read %d/%lu bytes", rc, jpg_size-i);
i += rc;
}
close(fd);
// ------------------------------------------------------------------- START
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, jpg_buffer, jpg_size);
rc = jpeg_read_header(&cinfo, TRUE);
if (rc != 1) {
// syslog(LOG_ERR, "File does not seem to be a normal JPEG");
return false;
}
jpeg_start_decompress(&cinfo);
width = cinfo.output_width;
height = cinfo.output_height;
pixel_size = cinfo.output_components;
row_stride = pixel_size * ((width + 15) & ~0x0F);
bmp_size = height * row_stride;
bmp_buffer = (unsigned char*) malloc(bmp_size);
while (cinfo.output_scanline < cinfo.output_height) {
unsigned char *buffer_array[1];
buffer_array[0] = bmp_buffer + (cinfo.output_scanline) * row_stride;
jpeg_read_scanlines(&cinfo, buffer_array, 1);
}
// syslog(LOG_INFO, "Proc: Done reading scanlines");
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
// And free the input buffer
free(jpg_buffer);
// -------------------------------------------------------------------- DONE
image->bpp = 3;
image->width = width;
image->height = height;
image->buffer = bmp_buffer;
image->type = VC_IMAGE_RGB888;
image->pitch = row_stride;
return true;
}