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