-
Notifications
You must be signed in to change notification settings - Fork 0
/
jpeg.cpp
124 lines (99 loc) · 3.36 KB
/
jpeg.cpp
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "jpeg.h"
#include <cstdio>
#include <cstdlib>
#include <jpeglib.h>
#include <stdexcept>
void read_jpeg_header(const char* filename, int& width, int& height)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE* infile;
/* create jpeg decompress object */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
/* set input file name */
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_src(&cinfo, infile);
/* read header */
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
width = cinfo.output_width;
height = cinfo.output_height;
}
void read_jpeg(const char* filename, unsigned char* image, int width, int height)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE* infile;
JSAMPROW row_pointer; /* pointer to a row */
int j, k;
/* create jpeg decompress object */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
/* set input file name */
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_src(&cinfo, infile);
/* read header */
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
if (width != cinfo.output_width || height != cinfo.output_height) {
throw std::runtime_error("Error: Actual JPEG resolution does not match the provided one.");
}
row_pointer = (JSAMPROW)malloc(sizeof(JSAMPLE) * (width)*3);
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, &row_pointer, 1);
for (j = 0; j < width; j++) {
for (k = 0; k < 3; k++) {
image[(cinfo.output_scanline - 1) * width * 3 + j * 3 + k] = (unsigned char)row_pointer[3 * j + k];
}
}
}
jpeg_finish_decompress(&cinfo);
fclose(infile);
free(row_pointer);
jpeg_destroy_decompress(&cinfo);
}
void write_jpeg(const char* filename, unsigned char* image, int width, int height)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE* outfile;
JSAMPROW row_pointer = (JSAMPROW)malloc(sizeof(JSAMPLE) * width * 3); /* pointer to a row */
int j, k;
/* create jpeg compress object */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
/* set output file name */
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
/* set parameters */
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, TRUE);
jpeg_start_compress(&cinfo, TRUE);
while (cinfo.next_scanline < cinfo.image_height) {
/* this loop converts each element to JSAMPLE */
for (j = 0; j < width; j++) {
for (k = 0; k < 3; k++) {
row_pointer[3 * j + k] = (JSAMPLE)image[cinfo.next_scanline * width * 3 + j * 3 + k];
}
}
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
free(row_pointer);
jpeg_destroy_compress(&cinfo);
}