blob: 54e40426a00edde6c777753a3325c17969126d2d [file] [log] [blame]
Brian Silverman5b3e51e2013-03-29 22:53:44 -07001#include "vision/JPEGRoutines.h"
2
Brian Silverman6ae77dd2013-03-29 22:28:08 -07003#include <stdio.h>
4#include <unistd.h>
5#include <stdlib.h>
6#include <sys/mman.h>
7#include <errno.h>
8#include <string.h>
9
10#include "aos/common/time.h"
11#include "opencv2/opencv.hpp"
Brian Silverman6ae77dd2013-03-29 22:28:08 -070012
Brian Silverman5b3e51e2013-03-29 22:53:44 -070013#include "vision/OpenCVWorkTask.h"
Brian Silverman6ae77dd2013-03-29 22:28:08 -070014
15namespace frc971 {
16namespace vision {
17
Brian Silverman6ae77dd2013-03-29 22:28:08 -070018/* This is also adapted from libjpeg to be used on decompression tables rather than
19 * compression tables as it was origionally intended
20 */
21void decompress_add_huff_table (j_decompress_ptr cinfo,
22 JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
23/* Define a Huffman table */
24{
25 int nsymbols, len;
26
27 if (*htblptr == NULL)
28 *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
29
30 /* Copy the number-of-symbols-of-each-code-length counts */
31 memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
32
33 /* Validate the counts. We do this here mainly so we can copy the right
34 * number of symbols from the val[] array, without risking marching off
35 * the end of memory. jchuff.c will do a more thorough test later.
36 */
37 nsymbols = 0;
38 for (len = 1; len <= 16; len++)
39 nsymbols += bits[len];
40 if (nsymbols < 1 || nsymbols > 256){
41 fprintf(stderr,"%s:%d: Error, bad huffman table",__FILE__,__LINE__);
42 exit(-1);
43 }
44
45 memcpy((*htblptr)->huffval, val, nsymbols * sizeof(uint8_t));
46
47}
48
49/* standard_huff_tables is taken from libjpeg compression stuff
50 * and is here used to set up the same tables in the decompression structure.
51 */
52void standard_huff_tables (j_decompress_ptr cinfo)
53 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
54 /* IMPORTANT: these are only valid for 8-bit data precision! */
55{
56 static const UINT8 bits_dc_luminance[17] =
57 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
58 static const UINT8 val_dc_luminance[] =
59 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
60
61 static const UINT8 bits_dc_chrominance[17] =
62 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
63 static const UINT8 val_dc_chrominance[] =
64 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
65
66 static const UINT8 bits_ac_luminance[17] =
67 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
68 static const UINT8 val_ac_luminance[] =
69 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
70 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
71 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
72 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
73 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
74 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
75 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
76 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
77 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
78 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
79 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
80 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
81 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
82 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
83 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
84 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
85 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
86 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
87 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
88 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
89 0xf9, 0xfa };
90
91 static const UINT8 bits_ac_chrominance[17] =
92 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
93 static const UINT8 val_ac_chrominance[] =
94 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
95 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
96 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
97 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
98 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
99 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
100 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
101 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
102 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
103 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
104 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
105 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
106 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
107 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
108 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
109 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
110 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
111 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
112 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
113 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
114 0xf9, 0xfa };
115
116 decompress_add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
117 bits_dc_luminance, val_dc_luminance);
118 decompress_add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
119 bits_ac_luminance, val_ac_luminance);
120 decompress_add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
121 bits_dc_chrominance, val_dc_chrominance);
122 decompress_add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
123 bits_ac_chrominance, val_ac_chrominance);
124}
125
126
127
128
129void process_jpeg(unsigned char *out,unsigned char *image,size_t size){
130 struct jpeg_decompress_struct cinfo;
131 struct jpeg_error_mgr jerr;
132
133 static aos::time::Time timestamp_old = aos::time::Time::Now();
134 aos::time::Time timestamp_start = aos::time::Time::Now();
135
136
137 cinfo.err = jpeg_std_error( &jerr );
138 cinfo.out_color_space = JCS_RGB;
139 jpeg_create_decompress( &cinfo );
140 //jpeg_stdio_src( &cinfo, infile );
141 jpeg_mem_src(&cinfo,image,size);
142
143 jpeg_read_header( &cinfo, TRUE );
144 standard_huff_tables (&cinfo);
145
146
147// printf( "JPEG File Information: \n" );
148// printf( "Image width and height: %d pixels and %d pixels.\n", cinfo.image_width, cinfo.image_height );
149// printf( "Color components per pixel: %d.\n", cinfo.num_components );
150// printf( "Color space: %d.\n", cinfo.jpeg_color_space );
151 printf("JpegDecompressed\n");
152
153 jpeg_start_decompress( &cinfo );
154
155 int offset = 0;
156 int step = cinfo.num_components * cinfo.image_width;
157 unsigned char *buffers[cinfo.image_height];
158 for (int i = cinfo.image_height - 1; i >= 0; --i) {
159 buffers[i] = &out[offset];
160 offset += step;
161 }
162
163 while( cinfo.output_scanline < cinfo.image_height )
164 {
165 jpeg_read_scanlines(&cinfo, &buffers[cinfo.output_scanline],
166 cinfo.image_height - cinfo.output_scanline);
167 }
168
169 /* This used to do BGR to RGB conversions inline */
170/*
171 for (int i = 0; i < (int)(cinfo.image_height * cinfo.image_width * 3); i+= 3) {
172 uint8_t b = out[i + 0];
173 uint8_t r = out[i + 2];
174 out[i + 0] = r;
175 out[i + 2] = b;
176 }
177*/
178 jpeg_finish_decompress( &cinfo );
179 jpeg_destroy_decompress( &cinfo );
180
181 aos::time::Time timestamp_end = aos::time::Time::Now();
182
183 double jpeg_part = ((timestamp_end - timestamp_start).nsec()) / 1000000000.0;
184 double longer_part = ((timestamp_end - timestamp_old).nsec()) / 1000000000.0;
185
186 printf("%g %g\n",jpeg_part / longer_part,1.0 / longer_part);
187
188 timestamp_old = timestamp_end;
189
190}
191
192} // namespace vision
193} // namespace frc971
194