GadgetSeed  0.9.6
jpegdec.c
[詳解]
1 /** @file
2  @brief JPEGデコード
3 
4  picojpeg を使用
5  https://github.com/richgel999/picojpeg
6 
7  @date 2017.11.12
8  @author Takashi SHUDO
9 */
10 
11 #include "picojpeg.h"
12 #include "tprintf.h"
13 #include "file.h"
14 #include "tkprintf.h"
15 #include "graphics.h"
16 
17 //#define DEBUGTBITS 0x02
18 #include "dtprintf.h"
19 
20 
21 #ifdef DEBUGTBITS
22 static const char scan_type_str[][6] = {
23  "GRAY",
24  "YH1V1",
25  "YH2V1",
26  "YH1V2",
27  "YH2V2"
28 };
29 #endif
30 
31 /*
32  * JPEGデータAPI
33  */
34 static unsigned char *jpeg_data_ptr;
35 static int flg_reduce = 0;
36 static void *image_ptr;
37 static int flg_draw = 0;
38 
39 static unsigned char pjpeg_data_need_bytes_callback(unsigned char *pBuf, unsigned char buf_size,
40  unsigned char *pBytes_actually_read, void *pCallback_data)
41 {
42  int rsize = 0;
43 
44  DTPRINTF(0x02, "pBuf %p, buf_size %d\n", pBuf, buf_size);
45 
46  (void)memorycopy(pBuf, jpeg_data_ptr, buf_size);
47  rsize = buf_size;
48  jpeg_data_ptr += buf_size;
49 
50  XDUMP(0x02, pBuf, rsize);
51 
52  *pBytes_actually_read = rsize;
53 
54  return 0;
55 }
56 
57 static pjpeg_image_info_t *image_info;
58 static PIXEL_DATA gbuf[16*16];
59 static short jpx, jpy;
60 
61 static void draw_pict(short px, short py, void *gbuf)
62 {
63  short gw = 8, gh = 8;
64 
65  if((px + 8) > image_info->m_width) {
66  gw = (image_info->m_width % 8);
67  DTPRINTF(0x02, "X=%d, Y=%d, W=%d\n", px, py, gw);
68  }
69  if((py + 8) > image_info->m_height) {
70  gh = (image_info->m_height % 8);
71  DTPRINTF(0x02, "X=%d, Y=%d, H=%d\n", px, py, gh);
72  }
73 
74  if(flg_draw != 0) {
75  if(flg_reduce != 0) {
76  set_forecolor(*(PIXEL_DATA *)gbuf);
77  draw_point(jpx + px/8, jpy + py/8);
78  } else {
79  draw_image(jpx + px, jpy + py, gw, gh, gbuf, 8);
80  }
81  } else {
82  PIXEL_DATA *dp, *sp = gbuf;;
83  if(flg_reduce != 0) {
84  dp = (PIXEL_DATA *)(image_ptr + ((image_info->m_width * py) + px) * sizeof(PIXEL_DATA));
85  *dp = *(PIXEL_DATA *)gbuf;
86  } else {
87  int x, y;
88  for(y=0; y<gh; y++) {
89  dp = (PIXEL_DATA *)(image_ptr + ((image_info->m_width * (py+y)) + px) * sizeof(PIXEL_DATA));
90  for(x=0; x<gw; x++) {
91  *dp = *sp;
92  dp ++;
93  sp ++;
94  }
95  }
96  }
97  }
98 }
99 
100 static void draw_block(short px, short py)
101 {
102  int i;
103  int dlen = image_info->m_MCUWidth * image_info->m_MCUHeight;
104  unsigned char *pr = image_info->m_pMCUBufR;
105  unsigned char *pg = image_info->m_pMCUBufG;
106  unsigned char *pb = image_info->m_pMCUBufB;
107 
108  DTPRINTF(0x02, "X = %d, Y = %d mcu = %d\n", px, py, dlen);
109  DTPRINTF(0x02, "R = %p, B = %p, G = %p\n", pr, pg, pb);
110  DTPRINTF(0x02, "W = %d, H = %d\n", image_info->m_MCUWidth, image_info->m_MCUHeight);
111 
112  for(i=0; i<dlen; i++) {
113  gbuf[i] = RGB(*pr, *pg, *pb);
114  pr ++;
115  pg ++;
116  pb ++;
117  }
118 
119  XDUMP(0x04, (unsigned char *)gbuf, dlen * sizeof(gbuf[0]));
120 
121  switch(image_info->m_scanType) {
122  case PJPG_GRAYSCALE:
123  // @todo JPEGグレースケール表示対応
124  break;
125 
126  case PJPG_YH1V1:
127  draw_pict(px, py, gbuf);
128  break;
129 
130  case PJPG_YH1V2:
131  draw_pict(px, py, gbuf);
132  draw_pict(px, py+8, &gbuf[64]);
133  break;
134 
135  case PJPG_YH2V1:
136  draw_pict(px, py, gbuf);
137  draw_pict(px+8, py, &gbuf[64]);
138  break;
139 
140  case PJPG_YH2V2:
141  draw_pict(px, py, gbuf);
142  draw_pict(px+8, py, &gbuf[64]);
143  draw_pict(px, py+8, &gbuf[128]);
144  draw_pict(px+8, py+8, &gbuf[192]);
145  break;
146 
147  default:
148  break;
149  }
150 }
151 
152 int get_jpeg_data_info(unsigned char *jpeg_data, pjpeg_image_info_t *jpeginfo, int reduce)
153 {
154  unsigned char status;
155 
156  jpeg_data_ptr = jpeg_data;
157  image_info = jpeginfo;
158  flg_reduce = reduce;
159 
160  status = pjpeg_decode_init(image_info, pjpeg_data_need_bytes_callback, 0, reduce);
161 
162  DTPRINTF(0x01, "status = %d\n", status);
163  if(status != 0) {
164  DTPRINTF(0x01, "pjpeg_decode_init() failed with status %u\n", status);
165  if(status == PJPG_UNSUPPORTED_MODE) {
166  DTPRINTF(0x01, "Progressive JPEG files are not supported.\n");
167  }
168  return -1;
169  }
170 
171  DTPRINTF(0x01, "IMAGE WIDTH = %d, HEIGHT = %d, COMPS = %d\n", image_info->m_width, image_info->m_height, image_info->m_comps);
172  DTPRINTF(0x01, "MCU WIDTH = %d, HEIGHT = %d\n", image_info->m_MCUWidth, image_info->m_MCUHeight);
173  DTPRINTF(0x01, "SCANTYPE = %s\n", scan_type_str[image_info->m_scanType]);
174 
175  return 0;
176 }
177 
178 /*
179  * JPEGファイルAPI
180  */
181 static int jpeg_fd = 0;
182 
183 static unsigned char pjpeg_file_need_bytes_callback(unsigned char *pBuf, unsigned char buf_size,
184  unsigned char *pBytes_actually_read, void *pCallback_data)
185 {
186  int rsize = 0;
187 
188  DTPRINTF(0x02, "pBuf %p, buf_size %d\n", pBuf, buf_size);
189 
190  rsize = read_file(jpeg_fd, pBuf, buf_size);
191  XDUMP(0x02, pBuf, rsize);
192 
193  *pBytes_actually_read = rsize;
194 
195  return 0;
196 }
197 
198 int get_jpeg_file_info(int fd, pjpeg_image_info_t *jpeginfo, int reduce)
199 {
200  unsigned char status;
201 
202  jpeg_fd = fd;
203  image_info = jpeginfo;
204  flg_reduce = reduce;
205 
206  status = pjpeg_decode_init(image_info, pjpeg_file_need_bytes_callback, 0, reduce);
207 
208  DTPRINTF(0x01, "status = %d\n", status);
209  if(status != 0) {
210  DTPRINTF(0x01, "pjpeg_decode_init() failed with status %u\n", status);
211  if(status == PJPG_UNSUPPORTED_MODE) {
212  DTPRINTF(0x01, "Progressive JPEG files are not supported.\n");
213  }
214  return -1;
215  }
216 
217  DTPRINTF(0x01, "IMAGE WIDTH = %d, HEIGHT = %d, COMPS = %d\n", image_info->m_width, image_info->m_height, image_info->m_comps);
218  DTPRINTF(0x01, "MCU WIDTH = %d, HEIGHT = %d\n", image_info->m_MCUWidth, image_info->m_MCUHeight);
219  DTPRINTF(0x01, "SCANTYPE = %s\n", scan_type_str[image_info->m_scanType]);
220 
221  return 0;
222 }
223 
224 
225 static int decode_proc_jpeg(void)
226 {
227  short gy = 0, gx = 0;
228 
229  for(;;) {
230  unsigned char status;
231 
232  status = pjpeg_decode_mcu();
233 
234  if(status != 0) {
235  if(status != PJPG_NO_MORE_BLOCKS) {
236  DTPRINTF(0x01, "pjpeg_decode_mcu() failed with status %u\n", status);
237  return -1;
238  }
239  break;
240  }
241 
242  XDUMP(0x04, image_info->m_pMCUBufR, 256);
243  XDUMP(0x04, image_info->m_pMCUBufG, 256);
244  XDUMP(0x04, image_info->m_pMCUBufB, 256);
245 
246  draw_block(gx, gy);
247 
248  gx += image_info->m_MCUWidth;
249  if(gx >= image_info->m_width) {
250  gx = 0;
251  gy += image_info->m_MCUHeight;
252  if(gy >= image_info->m_height) {
253  break;
254  }
255  }
256  }
257 
258  return 0;
259 }
260 
261 /*
262  * 描画API
263  */
264 int draw_jpeg(short px, short py)
265 {
266  jpx = px;
267  jpy = py;
268  flg_draw = 1;
269 
270  return decode_proc_jpeg();
271 }
272 
273 /*
274  * デコードAPI
275  */
276 int decode_jpeg(void *image)
277 {
278  image_ptr = image;
279  flg_draw = 0;
280 
281  return decode_proc_jpeg();
282 }
void draw_point(short x, short y)
点を描画する
Definition: graphics.c:447
void draw_image(short px, short py, short width, short height, void *image, short dw)
イメージデータを描画する
Definition: graphics.c:1840
アプリケーション(タスク)デバッグ用マクロ
ファイル
カーネル用機能限定printf
void set_forecolor(unsigned int color)
描画の色を設定する
Definition: graphics.c:370
void * memorycopy(void *dest, const void *src, unsigned int count)
メモリコピー
Definition: str.c:760
t_ssize read_file(int fd, void *buf, t_size count)
ファイルからデータを読み出す
Definition: file.c:188
グラフィックライブラリ
unsigned short PIXEL_DATA
$gsc グラフィックデバイスは24ビットカラー
Definition: graphics.h:17
機能限定printf