OpenCores
URL https://opencores.org/ocsvn/djpeg/djpeg/trunk

Subversion Repositories djpeg

[/] [djpeg/] [trunk/] [c_model/] [djpeg.c] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 hidemi
//////////////////////////////////////////////////////////////////////////////
2
// JPEGデコード
3
// 2005年10月26日 V1.0 
4
// All Rights Reserved, Copyright (c) Hidemi Ishihara
5
//////////////////////////////////////////////////////////////////////////////
6
//
7
// JPEGを入力するとBitmapを出力します。
8
// 
9
// % gcc -o djpeg fjpeg.c
10
// % djpeg 入力ファイル名 出力ファイル名
11
//////////////////////////////////////////////////////////////////////////////
12
#include <stdio.h>
13
#include <stdlib.h>
14
 
15
unsigned int BuffIndex;  // JPEGデータの位置
16
unsigned int BuffSize;   // JPEGデータの大きさ
17
unsigned int BuffX;      // 画像の横サイズ
18
unsigned int BuffY;      // 画像の縦サイズ
19
unsigned int BuffBlockX; // MCUの横個数
20
unsigned int BuffBlockY; // MCUの縦個数
21
unsigned char *Buff;     // 伸長したデータを入れるバッファ
22
 
23
unsigned char  TableDQT[4][64];  // 量子化テーブル
24
unsigned short TableDHT[4][162]; // ハフマンテーブル
25
 
26
unsigned short TableHT[4][16]; // ハフマンスタートテーブル
27
unsigned char  TableHN[4][16]; // ハフマンスタート番号
28
 
29
unsigned char BitCount = 0; // 圧縮データの読み込み位置
30
unsigned int LineData;      // 伸長に使うデータ
31
unsigned int NextData;      // 伸長に使うデータ
32
 
33
unsigned int PreData[3]; // DC成分用の貯めバッファ
34
 
35
// ジグザグテーブル
36
int zigzag_table[]={
37
     0, 1, 8, 16,9, 2, 3,10,
38
    17,24,32,25,18,11, 4, 5,
39
    12,19,26,33,40,48,41,34,
40
    27,20,13, 6, 7,14,21,28,
41
    35,42,49,56,57,50,43,36,
42
    29,22,15,23,30,37,44,51,
43
    58,59,52,45,38,31,39,46,
44
    53,60,61,54,47,55,62,63,
45
 
46
};
47
 
48
typedef unsigned short WORD;
49
typedef unsigned long DWORD;
50
typedef long LONG;
51
 
52
typedef struct tagBITMAPFILEHEADER {
53
  WORD    bfType;
54
  DWORD   bfSize;
55
  WORD    bfReserved1;
56
  WORD    bfReserved2;
57
  DWORD   bfOffBits;
58
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
59
 
60
typedef struct tagBITMAPINFOHEADER{
61
  DWORD  biSize;
62
  LONG   biWidth;
63
  LONG   biHeight;
64
  WORD   biPlanes;
65
  WORD   biBitCount;
66
  DWORD  biCompression;
67
  DWORD  biSizeImage;
68
  LONG   biXPelsPerMeter;
69
  LONG   biYPelsPerMeter;
70
  DWORD  biClrUsed;
71
  DWORD  biClrImportant;
72
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
73
 
74
//////////////////////////////////////////////////////////////////////////////
75
// Bitmapを出力する
76
// file: ファイル名
77
// x,y:  画像のサイズ
78
// b:    バイトカウント(1ドット辺りのバイト数)
79
//////////////////////////////////////////////////////////////////////////////
80
void BmpSave(unsigned char *file,unsigned char *buff,
81 9 hidemi
             unsigned int x,unsigned int y,unsigned int b){
82 3 hidemi
  BITMAPFILEHEADER lpBf;
83
  BITMAPINFOHEADER lpBi;
84
  unsigned char tbuff[4];
85
  FILE *fp;
86
  unsigned char str;
87
  int i,k;
88
 
89
  if((fp = fopen(file,"wb")) == NULL){
90
    perror(0);
91
    exit(0);
92
  }
93
 
94
  // ファイルヘッダの設定
95
  tbuff[0] = 'B';
96
  tbuff[1] = 'M';
97
  fwrite(tbuff,2,1,fp);
98
  tbuff[3] = ((14 +40 +x *y *b) >> 24) & 0xff;
99
  tbuff[2] = ((14 +40 +x *y *b) >> 16) & 0xff;
100
  tbuff[1] = ((14 +40 +x *y *b) >>  8) & 0xff;
101
  tbuff[0] = ((14 +40 +x *y *b) >>  0) & 0xff;
102
  fwrite(tbuff,4,1,fp);
103
  tbuff[1] = 0;
104
  tbuff[0] = 0;
105
  fwrite(tbuff,2,1,fp);
106
  fwrite(tbuff,2,1,fp);
107
  tbuff[3] = 0;
108
  tbuff[2] = 0;
109
  tbuff[1] = 0;
110
  tbuff[0] = 54;
111
  fwrite(tbuff,4,1,fp);
112
 
113
  // インフォメーションの設定
114
  lpBi.biSize            = 40;
115
  lpBi.biWidth           = x;
116
  lpBi.biHeight          = y;
117
  lpBi.biPlanes          = 1;
118
  lpBi.biBitCount        = b*8;
119
  lpBi.biCompression     = 0;
120
  lpBi.biSizeImage       = x*y*b;
121
  lpBi.biXPelsPerMeter   = 300;
122
  lpBi.biYPelsPerMeter   = 300;
123
  lpBi.biClrUsed         = 0;
124
  lpBi.biClrImportant    = 0;
125
  fwrite(&lpBi,1,40,fp);
126
 
127
  // 上下反転
128
  for(k=0;k<y/2;k++){
129
    for(i=0;i<x*3;i++){
130
      str = buff[k*x*3+i];
131
      buff[k*x*3+i] = buff[((y-1)*x*3 -k*x*3) +i];
132
      buff[((y-1)*x*3-k*x*3) +i] = str;
133
    }
134
  }
135
 
136
  fwrite(buff,1,x*y*b,fp);
137
 
138
  fclose(fp);
139
}
140
 
141
//////////////////////////////////////////////////////////////////////////////
142
// 1Byte取得
143
unsigned char get_byte(unsigned char *buff){
144
  if(BuffIndex >= BuffSize) return 0;
145
  return buff[BuffIndex++];
146
}
147
//////////////////////////////////////////////////////////////////////////////
148
// 2Byte取得
149
unsigned short get_word(unsigned char *buff){
150
  unsigned char h,l;
151
  h = get_byte(buff);
152
  l = get_byte(buff);
153
  return (h<<8)|l;
154
}
155
 
156
//////////////////////////////////////////////////////////////////////////////
157
// 32bitデータ取得(伸長時のみ使用する)
158
unsigned int get_data(unsigned char *buff){
159
  unsigned char str = 0;
160
  unsigned int data = 0;
161
  str = get_byte(buff);
162
  if(str ==0xff) if(get_byte(buff)== 0x00) str = 0xFF; else str = 0x00;
163
  data = str;
164
  str = get_byte(buff);
165
  if(str ==0xff) if(get_byte(buff)== 0x00) str = 0xFF; else str = 0x00;
166
  data = (data << 8) | str;
167
  str = get_byte(buff);
168
  if(str ==0xff) if(get_byte(buff)== 0x00) str = 0xFF; else str = 0x00;
169
  data = (data << 8) | str;
170
  str = get_byte(buff);
171
  if(str ==0xff) if(get_byte(buff)== 0x00) str = 0xFF; else str = 0x00;
172
  data = (data << 8) | str;
173
  //printf(" Get Data: %08x\n",data);
174
  return data;
175
}
176
 
177
//////////////////////////////////////////////////////////////////////////////
178
// APP0処理
179
void GetAPP0(unsigned char *buff){
180
  unsigned short data;
181
  unsigned char str;
182
  unsigned int i;
183
 
184
  data = get_word(buff); // Lp(レングス)
185
  // APP0は読まなくてもいいので取り合えずレングス分スキップする
186
  for(i=0;i<data-2;i++){
187
    str = get_byte(buff);
188
  }
189
  /*
190
  str = get_byte(buff);  // 識別子(5文字,"JFIF"と[00])
191
  str = get_byte(buff);
192
  str = get_byte(buff);
193
  str = get_byte(buff);
194
  str = get_byte(buff);
195
  data = get_word(buff); // バージョン
196
  str = get_byte(buff);  // 解像度の単位
197
  data = get_word(buff); // 横方向の解像度
198
  data = get_word(buff); // 縦方向の解像度
199
  data = get_word(buff); // サムネイルの横ピクセル数
200
  data = get_word(buff); // サムネイルの縦ピクセル数
201
  data = get_word(buff); // サムネイルデータ(ある場合だけ)
202
  */
203
}
204
 
205
//////////////////////////////////////////////////////////////////////////////
206
// DQT処理
207
void GetDQT(unsigned char *buff){
208
  unsigned short data;
209
  unsigned char str;
210
  unsigned int i;
211
  unsigned int tablenum;
212
 
213
  data = get_word(buff);
214
  str = get_byte(buff); // テーブル番号
215
 
216
  //printf("*** DQT Table %d\n",str);
217
  for(i=0;i<64;i++){
218
    TableDQT[str][i] = get_byte(buff);
219
    //printf(" %2d: %2x\n",i,TableDQT[str][i]);
220
  }
221
}
222
 
223
//////////////////////////////////////////////////////////////////////////////
224
// DHT処理
225
void GetDHT(unsigned char *buff){
226
  unsigned short data;
227
  unsigned char str;
228
  unsigned int i;
229
  unsigned char max,count;
230
  unsigned short ShiftData = 0x8000,HuffmanData =0x0000;
231
  unsigned int tablenum;
232
 
233
  data = get_word(buff);
234
  str = get_byte(buff);
235
 
236
  switch(str){
237
  case 0x00:
238
    tablenum = 0x00;
239
    break;
240
  case 0x10:
241
    tablenum = 0x01;
242
    break;
243
  case 0x01:
244
    tablenum = 0x02;
245
    break;
246
  case 0x11:
247
    tablenum = 0x03;
248
    break;
249
  }
250
 
251
  //printf("*** DHT Table/Number %d\n",tablenum);
252
  // テーブルを作成する
253
  max = 0;
254
  for(i=0;i<16;i++){
255
    count = get_byte(buff);
256
    TableHT[tablenum][i] = HuffmanData;
257
    TableHN[tablenum][i] = max;
258
    //printf(" %2d: %4x,%2x\n",i,TableHT[tablenum][i],TableHN[tablenum][i]);
259
    max = max + count;
260
    while(!(count==0)){
261
      HuffmanData += ShiftData;
262
      count--;
263
    }
264
    ShiftData = ShiftData >> 1; // 右に1bitシフトする
265
  }
266
 
267
  //printf("*** DHT Table %d\n",tablenum);
268
  for(i=0;i<max;i++){
269
    TableDHT[tablenum][i] = get_byte(buff);
270
    //printf(" %2d: %2x\n",i,TableDHT[tablenum][i]);
271
  }
272
}
273
 
274
//////////////////////////////////////////////////////////////////////////////
275
// SOF処理
276
void GetSOF(unsigned char *buff){
277
  unsigned short data;
278
  unsigned char str;
279
  unsigned int i;
280
  unsigned char count;
281
 
282
  data = get_word(buff);
283
  str = get_byte(buff);
284
  BuffY = get_word(buff); // 画像の横サイズ
285
  BuffX = get_word(buff); // 画像の縦サイズ
286
  count = get_byte(buff); // データのコンポーネント数
287
  for(i=0;i<count;i++){
288
    str = get_byte(buff); // コンポーネント番号
289
    str = get_byte(buff); // サンプリング比率
290
    str = get_byte(buff); // DQTテーブル番号
291
  }
292
 
293
  // MCUのサイズを算出する
294
  BuffBlockX = (int)(BuffX /16);
295
  if(BuffX % 16 >0) BuffBlockX++;
296
  BuffBlockY = (int)(BuffY /16);
297
  if(BuffY % 16 >0) BuffBlockY++;
298
  Buff = (unsigned char*)malloc(BuffBlockY*16*BuffBlockX*16*3);
299
 
300
  //printf(" size : %d x %d,(%d x %d)\n",BuffX,BuffY,BuffBlockX,BuffBlockY);
301
}
302
 
303
//////////////////////////////////////////////////////////////////////////////
304
// SOS処理
305
void GetSOS(unsigned char *buff){
306
  unsigned short data;
307
  unsigned char str;
308
  unsigned int i;
309
  unsigned char count;
310
 
311
  data = get_word(buff);
312
  count = get_byte(buff);
313
  for(i=0;i<count;i++){
314
    str = get_byte(buff);
315
    str = get_byte(buff);
316
  }
317
  str = get_byte(buff);
318
  str = get_byte(buff);
319
  str = get_byte(buff);
320
}
321
 
322
//////////////////////////////////////////////////////////////////////////////
323
// ハフマンデコード+逆量子化+逆ジグザグ
324
void HuffmanDecode(unsigned char *buff, unsigned char table, int *BlockData){
325
  unsigned int data;
326
  unsigned char zero;
327
  unsigned short code,huffman;
328
  unsigned char count =0;
329
  unsigned int BitData;
330
  unsigned int i;
331
  unsigned char tabledqt,tabledc,tableac,tablen;
332
  unsigned char ZeroCount,DataCount;
333
  int DataCode;
334
 
335
  for(i=0;i<64;i++) BlockData[i] = 0x0; // データのリセット
336
 
337
  // テーブル番号を設定する
338
  if(table ==0x00){
339
    tabledqt =0x00;
340
    tabledc =0x00;
341
    tableac =0x01;
342
  }else if(table ==0x01){
343
    tabledqt =0x01;
344
    tabledc  =0x02;
345
    tableac  =0x03;
346
  }else{
347
    tabledqt =0x01;
348
    tabledc  =0x02;
349
    tableac  =0x03;
350
  }
351
 
352
  count = 0; // 念のために
353
  while(count <64){
354
    // ビットカウントの位置が32を越えた場合、新たにデータを取得する
355
    if(BitCount >=32){
356
      LineData = NextData;
357
      NextData = get_data(buff);
358
      BitCount -= 32;
359
    }
360
    // Huffmanデコードで使用するデータに置き換える
361
    if(BitCount >0){
362
      BitData = (LineData << BitCount) | (NextData >> (32 - BitCount));
363
    }else{
364
      BitData = LineData;
365
    }
366
    //printf(" Haffuman BitData(%2d,%2d): %8x\n",table,count,BitData);
367
 
368
    // 使用するテーブルのセレクト
369
    if(count ==0) tablen = tabledc; else tablen = tableac;
370
    code = (unsigned short)(BitData >> 16); // コードは16ビット使用する
371
    // ハフマンコードがどのビット数にいるか割り出す
372
    for(i=0;i<16;i++) {
373
      //printf(" Haff hit(%2d:%2d): %8x,%8x\n",table,i,TableHT[tablen][i],code);
374
      if(TableHT[tablen][i]>code) break;
375
    }
376
    i--;
377
 
378
    code    = (unsigned short)(code >> (15 - i)); // コードの下位を揃える
379
    huffman = (unsigned short)(TableHT[tablen][i] >> (15 - i));
380
 
381
    //printf(" PreUse Dht Number(%2d): %8x,%8x,%8x\n",i,code,huffman,TableHN[tablen][i]);
382
 
383
    // ハフマンテーブルの場所を算出する
384
    code = code - huffman + TableHN[tablen][i];
385
 
386
    //printf(" Use Dht Number: %8x\n",code);
387
 
388
    ZeroCount = (TableDHT[tablen][code] >> 4) & 0x0F; // ゼロレングスの個数
389
    DataCount = (TableDHT[tablen][code]) & 0x0F;      // 続くデータのビット長
390
    //printf(" Dht Table: %8x,%8x\n",ZeroCount,DataCount);
391
    // ハフマンコードを抜き、続くデータを取得する
392
    DataCode  = (BitData << (i + 1)) >> (16 + (16 - DataCount));
393
    // 先頭ビットが"0"であれば負のデータ、上位ビットに1を立てて、1を足す
394
    //if(!(DataCode & (1<<(DataCount-1)))) DataCode=DataCode-(1<<DataCount)+1;
395
    if(!(DataCode & (1<<(DataCount-1))) && DataCount !=0){
396
      DataCode |= (~0) << DataCount;
397
      DataCode += 1;
398
    }
399
 
400
    //printf(" Use Bit: %d\n",(i + DataCount +1));
401
    BitCount += (i + DataCount +1); // 使用したビット数を加算する
402
 
403
    if(count ==0){
404
      // DC成分の場合、データとなる
405
      if(DataCount ==0) DataCode =0x0; // DataCountが0ならデータは0である
406
      PreData[table] += DataCode; // DC成分は加算しなければならない
407
      // 逆量子化+ジグザグ
408
      BlockData[zigzag_table[count]] =PreData[table]*TableDQT[tabledqt][count];
409
      count ++;
410
    }else{
411
      if(ZeroCount == 0x0 && DataCount == 0x0){
412 9 hidemi
        // AC成分でEOB符号が来た場合は終了する
413
        break;
414 3 hidemi
      }else if(ZeroCount ==0xF && DataCount == 0x0){
415 9 hidemi
        // ZRL符号が来た場合、15個のゼロデータとみなす
416
        count += 15;
417 3 hidemi
      }else{
418 9 hidemi
        count += ZeroCount;
419
        // 逆量子化+ジグザグ
420
        BlockData[zigzag_table[count]] = DataCode * TableDQT[tabledqt][count];
421 3 hidemi
      }
422 9 hidemi
      count ++;
423 3 hidemi
    }
424
  }
425
}
426
 
427
const int C1_16 = 4017; // cos( pi/16) x4096
428
const int C2_16 = 3784; // cos(2pi/16) x4096
429
const int C3_16 = 3406; // cos(3pi/16) x4096
430
const int C4_16 = 2896; // cos(4pi/16) x4096
431
const int C5_16 = 2276; // cos(5pi/16) x4096
432
const int C6_16 = 1567; // cos(6pi/16) x4096
433
const int C7_16 = 799;  // cos(7pi/16) x4096
434
 
435
//////////////////////////////////////////////////////////////////////////////
436
// 逆DCT
437
void DctDecode(int *BlockIn, int *BlockOut){
438
  int i;
439
  int s0,s1,s2,s3,s4,s5,s6,s7;
440
  int t0,t1,t2,t3,t4,t5,t6,t7;
441
 
442
  /*
443
  printf("-----------------------------\n");
444
  printf(" iDCT(In)\n");
445
  printf("-----------------------------\n");
446
  for(i=0;i<64;i++){
447
    printf("%2d: %8x\n",i,BlockIn[i]);
448
  }
449
  */
450
 
451
  for(i=0;i<8;i++) {
452
    s0 = (BlockIn[0] + BlockIn[4]) * C4_16;
453
    s1 = (BlockIn[0] - BlockIn[4]) * C4_16;
454
    s3 = (BlockIn[2] * C2_16) + (BlockIn[6] * C6_16);
455
    s2 = (BlockIn[2] * C6_16) - (BlockIn[6] * C2_16);
456
    s7 = (BlockIn[1] * C1_16) + (BlockIn[7] * C7_16);
457
    s4 = (BlockIn[1] * C7_16) - (BlockIn[7] * C1_16);
458
    s6 = (BlockIn[5] * C5_16) + (BlockIn[3] * C3_16);
459
    s5 = (BlockIn[5] * C3_16) - (BlockIn[3] * C5_16);
460
 
461
    /*
462
    printf("s0:%8x\n",s0);
463
    printf("s1:%8x\n",s1);
464
    printf("s2:%8x\n",s2);
465
    printf("s3:%8x\n",s3);
466
    printf("s4:%8x\n",s4);
467
    printf("s5:%8x\n",s5);
468
    printf("s6:%8x\n",s6);
469
    printf("s7:%8x\n",s7);
470
    */
471
 
472
    t0 = s0 + s3;
473
    t3 = s0 - s3;
474
    t1 = s1 + s2;
475
    t2 = s1 - s2;
476
    t4 = s4 + s5;
477
    t5 = s4 - s5;
478
    t7 = s7 + s6;
479
    t6 = s7 - s6;
480
 
481
    /*
482
    printf("t0:%8x\n",t0);
483
    printf("t1:%8x\n",t1);
484
    printf("t2:%8x\n",t2);
485
    printf("t3:%8x\n",t3);
486
    printf("t4:%8x\n",t4);
487
    printf("t5:%8x\n",t5);
488
    printf("t6:%8x\n",t6);
489
    printf("t7:%8x\n",t7);
490
    */
491
 
492
    s6 = (t5 + t6) * 181 / 256; // 1/sqrt(2)
493
    s5 = (t6 - t5) * 181 / 256; // 1/sqrt(2)
494
 
495
    /*
496
    printf("s5:%8x\n",s5);
497
    printf("s6:%8x\n",s6);
498
    */
499
 
500
    *BlockIn++ = (t0 + t7) >> 11;
501
    *BlockIn++ = (t1 + s6) >> 11;
502
    *BlockIn++ = (t2 + s5) >> 11;
503
    *BlockIn++ = (t3 + t4) >> 11;
504
    *BlockIn++ = (t3 - t4) >> 11;
505
    *BlockIn++ = (t2 - s5) >> 11;
506
    *BlockIn++ = (t1 - s6) >> 11;
507
    *BlockIn++ = (t0 - t7) >> 11;
508
  }
509
 
510
  BlockIn -= 64;
511
 
512
  /*
513
  printf("-----------------------------\n");
514
  printf(" iDCT(Middle)\n");
515
  printf("-----------------------------\n");
516
  for(i=0;i<64;i++){
517
    printf("%2d: %8x\n",i,BlockIn[i]);
518
  }
519
  */
520
 
521
  for(i=0;i<8;i++){
522
    s0 = (BlockIn[ 0] + BlockIn[32]) * C4_16;
523
    s1 = (BlockIn[ 0] - BlockIn[32]) * C4_16;
524
    s3 = BlockIn[16] * C2_16 + BlockIn[48] * C6_16;
525
    s2 = BlockIn[16] * C6_16 - BlockIn[48] * C2_16;
526
    s7 = BlockIn[ 8] * C1_16 + BlockIn[56] * C7_16;
527
    s4 = BlockIn[ 8] * C7_16 - BlockIn[56] * C1_16;
528
    s6 = BlockIn[40] * C5_16 + BlockIn[24] * C3_16;
529
    s5 = BlockIn[40] * C3_16 - BlockIn[24] * C5_16;
530
 
531
    /*
532
    printf("s0:%8x\n",s0);
533
    printf("s1:%8x\n",s1);
534
    printf("s2:%8x\n",s2);
535
    printf("s3:%8x\n",s3);
536
    printf("s4:%8x\n",s4);
537
    printf("s5:%8x\n",s5);
538
    printf("s6:%8x\n",s6);
539
    printf("s7:%8x\n",s7);
540
    */
541
 
542
    t0 = s0 + s3;
543
    t1 = s1 + s2;
544
    t2 = s1 - s2;
545
    t3 = s0 - s3;
546
    t4 = s4 + s5;
547
    t5 = s4 - s5;
548
    t6 = s7 - s6;
549
    t7 = s6 + s7;
550
 
551
    /*
552
    printf("t0:%8x\n",t0);
553
    printf("t1:%8x\n",t1);
554
    printf("t2:%8x\n",t2);
555
    printf("t3:%8x\n",t3);
556
    printf("t4:%8x\n",t4);
557
    printf("t5:%8x\n",t5);
558
    printf("t6:%8x\n",t6);
559
    printf("t7:%8x\n",t7);
560
    */
561
 
562
    s5 = (t6 - t5) * 181 / 256; // 1/sqrt(2)
563
    s6 = (t5 + t6) * 181 / 256; // 1/sqrt(2)
564
 
565
    /*
566
    printf("s5:%8x\n",s5);
567
    printf("s6:%8x\n",s6);
568
    */
569
 
570
    BlockOut[ 0] = ((t0 + t7) >> 15);
571
    BlockOut[56] = ((t0 - t7) >> 15);
572
    BlockOut[ 8] = ((t1 + s6) >> 15);
573
    BlockOut[48] = ((t1 - s6) >> 15);
574
    BlockOut[16] = ((t2 + s5) >> 15);
575
    BlockOut[40] = ((t2 - s5) >> 15);
576
    BlockOut[24] = ((t3 + t4) >> 15);
577
    BlockOut[32] = ((t3 - t4) >> 15);
578
 
579
    BlockIn++;
580
    BlockOut++;
581
  }
582
  BlockOut-=8;
583
  /*
584
  printf("-----------------------------\n");
585
  printf(" iDCT(Out)\n");
586
  printf("-----------------------------\n");
587
  for(i=0;i<8;i++){
588
    printf(" %2d: %04x;\n",i+ 0,BlockOut[i+ 0]&0xFFFF);
589
    printf(" %2d: %04x;\n",i+56,BlockOut[i+56]&0xFFFF);
590
    printf(" %2d: %04x;\n",i+ 8,BlockOut[i+ 8]&0xFFFF);
591
    printf(" %2d: %04x;\n",i+48,BlockOut[i+48]&0xFFFF);
592
    printf(" %2d: %04x;\n",i+16,BlockOut[i+16]&0xFFFF);
593
    printf(" %2d: %04x;\n",i+40,BlockOut[i+40]&0xFFFF);
594
    printf(" %2d: %04x;\n",i+24,BlockOut[i+24]&0xFFFF);
595
    printf(" %2d: %04x;\n",i+32,BlockOut[i+32]&0xFFFF);
596
  }
597
  */
598
}
599
 
600
//////////////////////////////////////////////////////////////////////////////
601
// 4:1:1のデコード処理
602
void Decode411(unsigned char *buff, int *BlockY, int *BlockCb, int *BlockCr){
603
  int BlockHuffman[64];
604
  int BlockYLT[64];
605
  int BlockYRT[64];
606
  int BlockYLB[64];
607
  int BlockYRB[64];
608
  unsigned int i;
609
 
610
  // 輝度(左上)
611
  //printf("Block:00\n");
612
  HuffmanDecode(buff,0x00,BlockHuffman);
613
  DctDecode(BlockHuffman,BlockYLT);
614
  // 輝度(右上)
615
  //printf("Block:02\n");
616
  HuffmanDecode(buff,0x00,BlockHuffman);
617
  DctDecode(BlockHuffman,BlockYRT);
618
  // 輝度(左下)
619
  //printf("Block:03\n");
620
  HuffmanDecode(buff,0x00,BlockHuffman);
621
  DctDecode(BlockHuffman,BlockYLB);
622
  // 輝度(右下)
623
  //printf("Block:04\n");
624
  HuffmanDecode(buff,0x00,BlockHuffman);
625
  DctDecode(BlockHuffman,BlockYRB);
626
  // 青色差
627
  //printf("Block:10\n");
628
  HuffmanDecode(buff,0x01,BlockHuffman);
629
  DctDecode(BlockHuffman,BlockCb);
630
  // 赤色差
631
  //printf("Block:11\n");
632
  HuffmanDecode(buff,0x02,BlockHuffman);
633
  DctDecode(BlockHuffman,BlockCr);
634
 
635
  // ブロックサイズを16x16にする
636
  for(i=0;i<64;i++){
637
    BlockY[(int)(i/8) *16 +(i % 8)] = BlockYLT[i];
638
    BlockY[(int)(i/8) *16 +(i % 8)+8] = BlockYRT[i];
639
    BlockY[(int)(i/8) *16 +(i % 8)+128] = BlockYLB[i];
640
    BlockY[(int)(i/8) *16 +(i % 8)+128+8] = BlockYRB[i];
641
  }
642
}
643
 
644
//////////////////////////////////////////////////////////////////////////////
645
// YUV→RGBに変換
646
void DecodeYUV(int *y, int *cb, int *cr, unsigned char *rgb){
647
  int r,g,b;
648
  int p,i;
649
 
650
  //printf("----RGB----\n");
651
  for(i=0;i<256;i++){
652
    p = ((int)(i/32) * 8) + ((int)((i % 16)/2));
653
    r = 128 + y[i] + cr[p]*1.402;
654
    r = (r & 0xffffff00) ? (r >> 24) ^ 0xff : r;
655
    g = 128 + y[i] - cb[p]*0.34414 - cr[p]*0.71414;
656
    g = (g & 0xffffff00) ? (g >> 24) ^ 0xff : g;
657
    b = 128 + y[i] + cb[p]*1.772;
658
    b = (b & 0xffffff00) ? (b >> 24) ^ 0xff : b;
659
    rgb[i*3+0] = b;
660
    rgb[i*3+1] = g;
661
    rgb[i*3+2] = r;
662
    /*
663
    printf("[RGB]%3d: %3x,%3x,%3x = %2x,%2x,%2x\n",i,
664 9 hidemi
           y[i]&0x1FF,cr[p]&0x1FF,cb[p]&0x1FF,
665
           rgb[i*3+2],rgb[i*3+1],rgb[i*3+0]);
666 3 hidemi
    */
667
  }
668
}
669
 
670
//////////////////////////////////////////////////////////////////////////////
671
// イメージのデコード
672
void Decode(unsigned char *buff,unsigned char *rgb){
673
  int BlockY[256];
674
  int BlockCb[256];
675
  int BlockCr[256];
676
  int x,y,i,p;
677
 
678
  for(y=0;y<BuffBlockY;y++){
679
    for(x=0;x<BuffBlockX;x++){
680
      Decode411(buff,BlockY,BlockCb,BlockCr); // 4:1:1のデコード
681
      DecodeYUV(BlockY,BlockCb,BlockCr,rgb);  // YUV→RGB変換
682
      for(i=0;i<256;i++){
683 9 hidemi
        if((x*16+(i%16)<BuffX) && (y*16+i/16<BuffY)){
684
          p=y*16*BuffX*3+x*16*3+(int)(i/16)*BuffX*3+(i%16)*3;
685
          Buff[p+0] = rgb[i*3+0];
686
          Buff[p+1] = rgb[i*3+1];
687
          Buff[p+2] = rgb[i*3+2];
688
          /*
689
          printf("RGB[%4d,%4d]: %2x,%2x,%2x\n",x*16+(i%16),y*16+i/16,
690
                 rgb[i*3+2],rgb[i*3+1],rgb[i*3+0]);
691
          */
692
        }
693 3 hidemi
      }
694
    }
695
  }
696
}
697
 
698
//////////////////////////////////////////////////////////////////////////////
699
// デコード
700
void JpegDecode(unsigned char *buff){
701
  unsigned short data;
702
  unsigned int i;
703
  unsigned int Image =0;
704
  unsigned char RGB[256*3];
705
  while(!(BuffIndex >= BuffSize)){
706
    if(Image ==0){
707
      data = get_word(buff);
708
      switch(data){
709
      case 0xFFD8: // SOI
710 9 hidemi
        break;
711 3 hidemi
      case 0xFFE0: // APP0
712 9 hidemi
        GetAPP0(buff);
713
        break;
714 3 hidemi
      case 0xFFDB: // DQT
715 9 hidemi
        GetDQT(buff);
716
        break;
717 3 hidemi
      case 0xFFC4: // DHT
718 9 hidemi
        GetDHT(buff);
719
        break;
720 3 hidemi
      case 0xFFC0: // SOF
721 9 hidemi
        GetSOF(buff);
722
        break;
723 3 hidemi
      case 0xFFDA: // SOS
724 9 hidemi
        GetSOS(buff);
725
        Image = 1;
726
        // データの準備
727
        PreData[0] = 0x00;
728
        PreData[1] = 0x00;
729
        PreData[2] = 0x00;
730
        LineData = get_data(buff);
731
        NextData = get_data(buff);
732
        BitCount =0;
733
        break;
734 3 hidemi
      case 0xFFD9: // EOI
735 9 hidemi
        break;
736 3 hidemi
      default:
737 9 hidemi
        // 判別できないヘッダーは読み飛ばす
738
        if((data & 0xFF00) == 0xFF00 && !(data == 0xFF00)){
739
          data = get_word(buff);
740
          for(i=0;i<data-2;i++){
741
            get_byte(buff);
742
          }
743
        }
744
        break;
745 3 hidemi
      }
746
    }else{
747
      // 伸長(SOSが来ている)
748
      Decode(buff,RGB);
749
    }
750
  }
751
}
752
 
753
//////////////////////////////////////////////////////////////////////////////
754
// メイン関数
755
//////////////////////////////////////////////////////////////////////////////
756
int main(int argc, char* argv[])
757
{
758
  unsigned char *buff;
759
  FILE *fp;
760
 
761
  if((fp = fopen(argv[1],"rb")) == NULL){
762
    perror(0);
763
    exit(0);
764
  }
765
 
766
  // ファイルサイズを取得する
767
  BuffSize = 0;
768
  while(!feof(fp)){
769
    fgetc(fp);
770
    BuffSize ++;
771
  }
772
  BuffSize--;
773
  rewind(fp); // ファイルポインタを最初に戻す
774
 
775
  buff = (unsigned char *)malloc(BuffSize); // バッファを確保する
776
  fread(buff,1,BuffSize,fp);                // バッファに読み込む
777
  BuffIndex = 0;
778
  JpegDecode(buff);                         // JPEGデコードする
779
  BmpSave(argv[2],Buff,BuffX,BuffY,3);      // Bitmapに保存する
780
 
781
  // 全て開放します
782
  fclose(fp);
783
  free(buff);
784
  free(Buff);
785
 
786
  return 0;
787
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.