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