/* * enclib.h * * Created on: 2010/04/12 * Author: produce */ #ifndef ENCLIB_H_ #define ENCLIB_H_ #include #include #include #include #define VSYNC 4096 #define HSYNC 4096 #define PARET 256 #define BIT_SIZE 32 #define PARET_SIZE 4 #define MCU_NUMBER 10 #define MCU_VSIZE 8 #define MCU_HSIZE 8 typedef unsigned int DWORD; typedef unsigned short int BWORD; typedef unsigned char BBYTE; typedef struct _DATASET_ { BBYTE buf[0xffffff]; int buf_pot; int addres; } DATASET; typedef struct _AREA_ { int X; int Y; //int Space; //int Diag; //double Deg; } SQUARE; typedef union _DWORD_AREA_ { DWORD byte32; struct _BYTE16_ { BWORD byte31_16; BWORD byte15_0; } BYTE16; struct _BYTE8_ { BBYTE byte31_24; BBYTE byte23_16; BBYTE byte15_8; BBYTE byte7_0; } BYTE8; struct _BYTE4_ { BBYTE byte31_28 : 4; BBYTE byte27_24 : 4; BBYTE byte23_20 : 4; BBYTE byte19_16 : 4; BBYTE byte15_12 : 4; BBYTE byte11_8 : 4; BBYTE byte7_4 : 4; BBYTE byte3_0 : 4; } BYTE4; struct _BYTE2_ { BBYTE byte31_30 : 2; BBYTE byte29_28 : 2; BBYTE byte27_26 : 2; BBYTE byte25_24 : 2; BBYTE byte23_22 : 2; BBYTE byte21_20 : 2; BBYTE byte19_18 : 2; BBYTE byte17_16 : 2; BBYTE byte15_14 : 2; BBYTE byte13_12 : 2; BBYTE byte11_10 : 2; BBYTE byte9_8 : 2; BBYTE byte7_6 : 2; BBYTE byte5_4 : 2; BBYTE byte3_2 : 2; BBYTE byte1_0 : 2; } BYTE2; struct _BIT_ { BBYTE bit31 : 1; BBYTE bit30 : 1; BBYTE bit29 : 1; BBYTE bit28 : 1; BBYTE bit27 : 1; BBYTE bit26 : 1; BBYTE bit25 : 1; BBYTE bit24 : 1; BBYTE bit23 : 1; BBYTE bit22 : 1; BBYTE bit21 : 1; BBYTE bit20 : 1; BBYTE bit19 : 1; BBYTE bit18 : 1; BBYTE bit17 : 1; BBYTE bit16 : 1; BBYTE bit15 : 1; BBYTE bit14 : 1; BBYTE bit13 : 1; BBYTE bit12 : 1; BBYTE bit11 : 1; BBYTE bit10 : 1; BBYTE bit9 : 1; BBYTE bit8 : 1; BBYTE bit7 : 1; BBYTE bit6 : 1; BBYTE bit5 : 1; BBYTE bit4 : 1; BBYTE bit3 : 1; BBYTE bit2 : 1; BBYTE bit1 : 1; BBYTE bit0 : 1; } BIT; } WORDMAP; typedef struct _BMPFILEHEDER_ { BWORD BM; DWORD FileSize; //byte BWORD reserve1; BWORD reserve2; DWORD offset; //byte } BMPFILEh; typedef struct _BMPHEADERV5_ { DWORD HeaderSize; //0x000e DWORD tH; // pix DWORD tV; // pix BWORD Plean; //1 BWORD PixBit; //0,1,2,4,8,16,32 DWORD Pressure; //0,1,2,3,4,5 DWORD DataSize; // byte DWORD tHpix; // pix/m DWORD tVpix; // pix/m DWORD indexColor; DWORD impColor; DWORD RMask; DWORD GMask; DWORD BMask; DWORD AMask; DWORD ColorSpace; DWORD CIExyz[3][3]; DWORD RGanmma; DWORD GGanmma; DWORD BGanmma; DWORD rendring; // 1,2,4,8 DWORD profileOffset; DWORD profileSize; DWORD reserve; BBYTE parret[PARET][PARET_SIZE]; } BMPDATAv5h; typedef struct _BMPDATAHEADER_ { BMPFILEh BMPFH; BMPDATAv5h BMPDH; BBYTE red[VSYNC][HSYNC]; BBYTE green[VSYNC][HSYNC]; BBYTE blue[VSYNC][HSYNC]; BBYTE alpha[VSYNC][HSYNC]; //DWORD Hsize; //DWORD Vsize; } EBMP; typedef enum _JPEGMARK_ { MKR = 0xFF, //マーカスタート APP0 = 0xE0, //アプリセグメント APP1 = 0xE1, APP2 = 0xE2, APP3 = 0xE3, APP4 = 0xE4, APP5 = 0xE5, APP6 = 0xE6, APP7 = 0xE7, APP8 = 0xE8, APP9 = 0xE9, APP10 = 0xEA, APP11 = 0xEB, APP12 = 0xEC, APP13 = 0xED, APP14 = 0xEE, APP15 = 0xEF, SOF0 = 0xC0, //基本DCT SOF1 = 0xC1, //拡張シーケンシャルDCT SOF2 = 0xC2, //プログレッシブDCT SOF3 = 0xC3, //空間可逆 DHT = 0xC4, //ハフマンテーブル SOF5 = 0xC5, //差分シーケンシャルDCT SOF6 = 0xC6, //差分プログレッシブDCT SOF7 = 0xC7, //差分空間方式 JPG = 0xC8, //JPEG拡張のためのリザーブ SOF9 = 0xC9, //拡張シーケンシャルDCT SOF10 = 0xCA, //プログレッシブDCT SOF11 = 0xCB, //空間シーケンシャル可逆 DAC = 0xCC, //算術符号条件付け定義 SOF13 = 0xCD, //差分シーケンシャルDCT SOF14 = 0xCE, //差分プログレッシブDCT SOF15 = 0xCF, //差分空間 RST0 = 0xD0, //リスタートインターバル RST1 = 0xD1, RST2 = 0xD2, RST3 = 0xD3, RST4 = 0xD4, RST5 = 0xD5, RST6 = 0xD6, RST7 = 0xD7, SOI = 0xD8, //画像開始 EOI = 0xD9, //画像終了 SOS = 0xDA, //スキャン開始 DQT = 0xDB, //量子化テーブル定義 DNL = 0xDC, //ライン数定義 DRI = 0xDD, //リスタートインターバル定義 DHP = 0xDE, //ハイアラーキカル・プログレッション定義 EXP = 0xDF, //参照成分拡大 COM = 0xFE, //コメント TEM = 0x01, //算術符号で使用 REST = 0x02, RESD = 0xBF, } JPG_MARK; typedef struct _JProperty_ { DWORD kJFIFL; DWORD kJFIFV; DWORD CanDecode; // decode ok? DWORD Hsize; DWORD Vsize; DWORD Dim; // kouseisuu DWORD SamplePrecision; // sample seido BBYTE *comment; DWORD format; // 0:none 1:JFIF 2:JFXX BBYTE MajorRev; // version shousu jyoui BBYTE MinorRev; // version shousu kai DWORD units; // mitsudo 0:none 1:dot/inch 2:dot/cm DWORD Hdens; // yoko mitsudo DWORD Vdens; // tate mitsudo DWORD HThumbnail; // samuneiru yokogaso DWORD VThumbnail; // samuneiru tategaso DWORD ExtensionCode; // 0x10:JPEG 0x11:1byte/pixel 0x13:3byte/pixel } JPRO; typedef struct _JPEG_LIB_ { JPRO JSetting; DATASET JPGDS; double MCU[MCU_NUMBER][MCU_VSIZE][MCU_HSIZE]; int PreDC[MCU_NUMBER]; } EJPG; WORDMAP WordField(DWORD data){ WORDMAP DD; DD.byte32=data; return DD; } WORDMAP ByteField(BWORD data){ WORDMAP DD; DD.BYTE16.byte15_0=data; return DD; } WORDMAP BitField(BBYTE data){ WORDMAP DD; DD.BYTE8.byte7_0=data; return DD; } //8bit書き込み //buf_adはビット位置で7~0 //nは書き込みビット数1~8 //bitは書き込みデータ void WriteByte(DATASET *DS,BBYTE bit,int n){ int m,ad = 0; int l = n - 1;//nの値を下げる const BBYTE masking[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; BBYTE *buff = &DS->buf[DS->addres]; // bitをMAB側からマスクする。 bit &= masking[l]; m = DS->buf_pot - n; if(m<0){ m = -m; buff[ad] |= bit >> (m-1); if(buff[ad]==0xFF){ ad++; buff[ad] = 0u; } ad++; bit &= masking[m-1]; m = 7 - ( m-1 ); } buff[ad] |= bit << (m+1); if(buff[ad]==0xFF){ ad++; buff[ad] = 0u; m = 7; } DS->buf_pot = m; DS->addres += ad; } //32bit書き込み用 void WriteWord(DATASET *DS,DWORD bit,int n){ BBYTE bit_save; const DWORD masking[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; if(n>24){ bit_save =(BBYTE)(bit >>(n-8)); WriteByte(DS,bit_save,8); n -= 8; } else ; if(n>16){ bit_save = (BBYTE)(bit >>(n-8)); WriteByte(DS,bit_save,8); n -= 8; } else ; if(n>8){ bit_save = (BBYTE)(bit >>(n-8)); WriteByte(DS,bit_save,8); n -= 8; } else ; if(n>0){ bit_save = (BBYTE)( bit & masking[n-1]); WriteByte(DS,bit_save,n); } else ; } void SettingBitAllay(BBYTE *buf,int bit_deep,WORDMAP *wm){ switch(bit_deep){ case 1 : buf[0] = wm->BIT.bit7; buf[1] = wm->BIT.bit6; buf[2] = wm->BIT.bit5; buf[3] = wm->BIT.bit4; buf[4] = wm->BIT.bit3; buf[5] = wm->BIT.bit2; buf[6] = wm->BIT.bit1; buf[7] = wm->BIT.bit0; break; case 2 : buf[0] = wm->BYTE2.byte7_6; buf[1] = wm->BYTE2.byte5_4; buf[2] = wm->BYTE2.byte3_2; buf[3] = wm->BYTE2.byte1_0; break; case 4 : buf[0] = wm->BYTE4.byte7_4; buf[1] = wm->BYTE4.byte3_0; break; default : buf[0] = wm->BYTE8.byte7_0; break; } } void BMPFileHeadReader(EBMP *bmph,long offset,FILE *fp){ fseek(fp,offset,SEEK_SET); // offset=SEEK_SET fread(&bmph->BMPFH.BM,sizeof(BWORD),1,fp); fread(&bmph->BMPFH.FileSize,sizeof(DWORD),1,fp); fread(&bmph->BMPFH.reserve1,sizeof(BWORD),1,fp); fread(&bmph->BMPFH.reserve2,sizeof(BWORD),1,fp); fread(&bmph->BMPFH.offset,sizeof(DWORD),1,fp); } void BMPDataHeadReader(EBMP *bmph,long offset,FILE *fp){ int i,prts; fseek(fp,offset,SEEK_SET); fread(&bmph->BMPDH.HeaderSize,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.tH,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.tV,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.Plean,sizeof(BWORD),1,fp); fread(&bmph->BMPDH.PixBit,sizeof(BWORD),1,fp); if(bmph->BMPDH.HeaderSize>=40){ fread(&bmph->BMPDH.Pressure,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.DataSize,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.tHpix,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.tVpix,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.indexColor,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.impColor,sizeof(DWORD),1,fp); } else ; if(bmph->BMPDH.HeaderSize>=64){ fread(&bmph->BMPDH.RMask,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.GMask,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.BMask,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.AMask,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.ColorSpace,sizeof(DWORD),1,fp); } else ; if(bmph->BMPDH.HeaderSize>=108){ fread(bmph->BMPDH.CIExyz[0],sizeof(DWORD),3,fp); fread(bmph->BMPDH.CIExyz[1],sizeof(DWORD),3,fp); fread(bmph->BMPDH.CIExyz[2],sizeof(DWORD),3,fp); fread(&bmph->BMPDH.RGanmma,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.GGanmma,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.BGanmma,sizeof(DWORD),1,fp); } else ; if(bmph->BMPDH.HeaderSize>=124){ fread(&bmph->BMPDH.rendring,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.profileOffset,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.profileSize,sizeof(DWORD),1,fp); fread(&bmph->BMPDH.reserve,sizeof(DWORD),1,fp); } else ; switch(bmph->BMPDH.PixBit){ case 1 : { prts=2; break; } case 2 : { prts=4; break; } case 4 : { prts=16; break; } case 8 : { prts=256; break; } default : { prts=0; break; } } for(i=0;iBMPDH.parret[i],sizeof(DWORD),1,fp); } } void BMPDataReader(EBMP *bmph,FILE *fp){ int hcnt,vcnt,h_inc; int hsize,vsize; DWORD buf_fp; WORDMAP FP_DAT; BMPFileHeadReader(bmph,0L,fp); BMPDataHeadReader(bmph,12L,fp); vsize = bmph->BMPDH.tV - 1; hsize = ( bmph->BMPDH.tH%4 )? ( bmph->BMPDH.tH + 4 - bmph->BMPDH.tH ) : bmph->BMPDH.tH; switch(bmph->BMPDH.PixBit){ case 1 : h_inc = 8; break; case 2 : h_inc = 4; break; case 4 : h_inc = 2; break; default : h_inc = 1; break; } for(vcnt=vsize;vcnt>=0;vcnt--){ for(hcnt=0;hcntblue[vcnt][hcnt], bmph->BMPDH.PixBit, &FP_DAT); SettingBitAllay( &bmph->green[vcnt][hcnt], bmph->BMPDH.PixBit, &FP_DAT); SettingBitAllay( &bmph->red[vcnt][hcnt], bmph->BMPDH.PixBit, &FP_DAT); SettingBitAllay( &bmph->alpha[vcnt][hcnt], bmph->BMPDH.PixBit, &FP_DAT); } } } #define kSqrt2 1.41421356 #define PAI 3.14159265 // 輝度量子化テーブル static const int kYQuantumT[8][8] = { {16, 11, 10, 16, 24, 40, 51, 61}, {12, 12, 14, 19, 26, 58, 60, 55}, {14, 13, 16, 24, 40, 57, 69, 56}, {14, 17, 22, 29, 51, 87, 80, 62}, {18, 22, 37, 56, 68, 109, 103, 77}, {24, 35, 55, 64, 81, 104, 113, 92}, {49, 64, 78, 87, 103, 121, 120, 101}, {72, 92, 95, 98, 112, 100, 103, 99} }; // 色差量子化テーブル static const int kCQuantumT[8][8] = { {17, 18, 24, 47, 99, 99, 99, 99}, {18, 21, 26, 66, 99, 99, 99, 99}, {24, 26, 56, 99, 99, 99, 99, 99}, {47, 66, 99, 99, 99, 99, 99, 99}, {99, 99, 99, 99, 99, 99, 99, 99}, {99, 99, 99, 99, 99, 99, 99, 99}, {99, 99, 99, 99, 99, 99, 99, 99}, {99, 99, 99, 99, 99, 99, 99, 99} }; // 輝度DC成分用 static const int kYDcSizeT[] = { // サイズテーブル 0x0002, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009 }; //輝度DC用 static const int kYDcCodeT[] = { // 符号語テーブル 0x0000, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x000e, 0x001e, 0x003e, 0x007e, 0x00fe, 0x01fe }; // 色差DC成分用 static const int kCDcSizeT[] = { // サイズテーブル 0x0002, 0x0002, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b }; //色差DC用 static const int kCDcCodeT[] = { // 符号語テーブル 0x0000, 0x0001, 0x0002, 0x0006, 0x000e, 0x001e, 0x003e, 0x007e, 0x00fe, 0x01fe, 0x03fe, 0x07fe }; // 輝度AC成分用 static const int kYAcSizeT[] = { // サイズテーブル 4, 2, 2, 3, 4, 5, 7, 8, 10, 16, 16, 4, 5, 7, 9, 11, 16, 16, 16, 16, 16, 5, 8, 10, 12, 16, 16, 16, 16, 16, 16, 6, 9, 12, 16, 16, 16, 16, 16, 16, 16, 6, 10, 16, 16, 16, 16, 16, 16, 16, 16, 7, 11, 16, 16, 16, 16, 16, 16, 16, 16, 7, 12, 16, 16, 16, 16, 16, 16, 16, 16, 8, 12, 16, 16, 16, 16, 16, 16, 16, 16, 9, 15, 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; //輝度AC用 static const int kYAcCodeT[] = { // 符号語テーブル 0x000a, 0x0000, 0x0001, 0x0004, 0x000b, 0x001a, 0x0078, 0x00f8, 0x03f6, 0xff82, 0xff83, 0x000c, 0x001b, 0x0079, 0x01f6, 0x07f6, 0xff84, 0xff85, 0xff86, 0xff87, 0xff88, 0x001c, 0x00f9, 0x03f7, 0x0ff4, 0xff89, 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0x003a, 0x01f7, 0x0ff5, 0xff8f, 0xff90, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0x003b, 0x03f8, 0xff96, 0xff97, 0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0x007a, 0x07f7, 0xff9e, 0xff9f, 0xffa0, 0xffa1, 0xffa2, 0xffa3, 0xffa4, 0xffa5, 0x007b, 0x0ff6, 0xffa6, 0xffa7, 0xffa8, 0xffa9, 0xffaa, 0xffab, 0xffac, 0xffad, 0x00fa, 0x0ff7, 0xffae, 0xffaf, 0xffb0, 0xffb1, 0xffb2, 0xffb3, 0xffb4, 0xffb5, 0x01f8, 0x7fc0, 0xffb6, 0xffb7, 0xffb8, 0xffb9, 0xffba, 0xffbb, 0xffbc, 0xffbd, 0x01f9, 0xffbe, 0xffbf, 0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc4, 0xffc5, 0xffc6, 0x01fa, 0xffc7, 0xffc8, 0xffc9, 0xffca, 0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf, 0x03f9, 0xffd0, 0xffd1, 0xffd2, 0xffd3, 0xffd4, 0xffd5, 0xffd6, 0xffd7, 0xffd8, 0x03fa, 0xffd9, 0xffda, 0xffdb, 0xffdc, 0xffdd, 0xffde, 0xffdf, 0xffe0, 0xffe1, 0x07f8, 0xffe2, 0xffe3, 0xffe4, 0xffe5, 0xffe6, 0xffe7, 0xffe8, 0xffe9, 0xffea, 0xffeb, 0xffec, 0xffed, 0xffee, 0xffef, 0xfff0, 0xfff1, 0xfff2, 0xfff3, 0xfff4, 0x07f9, 0xfff5, 0xfff6, 0xfff7, 0xfff8, 0xfff9, 0xfffa, 0xfffb, 0xfffc, 0xfffd, 0xfffe }; // 色差AC成分用 static const int kCAcSizeT[] = { // サイズテーブル 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 12, 4, 6, 8, 9, 11, 12, 16, 16, 16, 16, 5, 8, 10, 12, 15, 16, 16, 16, 16, 16, 5, 8, 10, 12, 16, 16, 16, 16, 16, 16, 6, 9, 16, 16, 16, 16, 16, 16, 16, 16, 6, 10, 16, 16, 16, 16, 16, 16, 16, 16, 7, 11, 16, 16, 16, 16, 16, 16, 16, 16, 7, 11, 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 10, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; // 色差AC用 static const int kCAcCodeT[] = { // 符号語テーブル 0x0000, 0x0001, 0x0004, 0x000a, 0x0018, 0x0019, 0x0038, 0x0078, 0x01f4, 0x03f6, 0x0ff4, 0x000b, 0x0039, 0x00f6, 0x01f5, 0x07f6, 0x0ff5, 0xff88, 0xff89, 0xff8a, 0xff8b, 0x001a, 0x00f7, 0x03f7, 0x0ff6, 0x7fc2, 0xff8c, 0xff8d, 0xff8e, 0xff8f, 0xff90, 0x001b, 0x00f8, 0x03f8, 0x0ff7, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0x003a, 0x01f6, 0xff97, 0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0x003b, 0x03f9, 0xff9f, 0xffa0, 0xffa1, 0xffa2, 0xffa3, 0xffa4, 0xffa5, 0xffa6, 0x0079, 0x07f7, 0xffa7, 0xffa8, 0xffa9, 0xffaa, 0xffab, 0xffac, 0xffad, 0xffae, 0x007a, 0x07f8, 0xffaf, 0xffb0, 0xffb1, 0xffb2, 0xffb3, 0xffb4, 0xffb5, 0xffb6, 0x00f9, 0xffb7, 0xffb8, 0xffb9, 0xffba, 0xffbb, 0xffbc, 0xffbd, 0xffbe, 0xffbf, 0x01f7, 0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc4, 0xffc5, 0xffc6, 0xffc7, 0xffc8, 0x01f8, 0xffc9, 0xffca, 0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf, 0xffd0, 0xffd1, 0x01f9, 0xffd2, 0xffd3, 0xffd4, 0xffd5, 0xffd6, 0xffd7, 0xffd8, 0xffd9, 0xffda, 0x01fa, 0xffdb, 0xffdc, 0xffdd, 0xffde, 0xffdf, 0xffe0, 0xffe1, 0xffe2, 0xffe3, 0x07f9, 0xffe4, 0xffe5, 0xffe6, 0xffe7, 0xffe8, 0xffe9, 0xffea, 0xffeb, 0xffec, 0x3fe0, 0xffed, 0xffee, 0xffef, 0xfff0, 0xfff1, 0xfff2, 0xfff3, 0xfff4, 0xfff5, 0x03fa, 0x7fc3, 0xfff6, 0xfff7, 0xfff8, 0xfff9, 0xfffa, 0xfffb, 0xfffc, 0xfffd, 0xfffe }; static const int kYEOBidx = 0; // EOBのインデックス static const int kYZRLidx = 151; // ZRLのインデックス static const int kCEOBidx = 0; // EOBのインデックス static const int kCZRLidx = 151; // ZRLのインデックス static const BBYTE kYSampleF = 0x22; // 輝度サンプリングファクタ(MCU内の縦横ユニット数2x2) static const BBYTE kCSampleF = 0x11; // 色差サンプリングファクタ(MCU内の縦横ユニット数1x1) static const int kDcDhtLength = 0x21; // DC用成分セグメントの長さ static const int kAcDhtLength = 0xb7; // AC用成分セグメントの長さ static const BBYTE kYDcDhtT[] = { // 輝度DC成分用 0xff, 0xc4, // マーカ 0x00, 0x1f, // パラメータ長 0x00, // クラス 0:DC, 識別子 0:輝度用 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, // 長さiの符号語数 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // パラメータ 0x08, 0x09, 0x0a, 0x0b }; static const BBYTE kCDcDhtT[] = { // 色差DC成分用 0xff, 0xc4, // マーカ 0x00, 0x1f, // パラメータ長 0x01, // クラス 0:DC, 識別子 1:色差用 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 長さiの符号語数 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // パラメータ 0x08, 0x09, 0x0a, 0x0b }; static const BBYTE kYAcDhtT[] = { // 輝度AC成分用 0xff, 0xc4, // マーカ 0x00, 0xb5, // パラメータ長 0x10, // クラス 1:AC, 識別子 0:輝度用 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, // 長さiの符号語数 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, // パラメータ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa }; static const BBYTE kCAcDhtT[] = { // 色差AC成分用 0xff, 0xc4, // マーカ 0x00, 0xb5, // パラメータ長 0x11, // クラス 1:AC, 識別子 1:色差用 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, // 長さiの符号語数 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, // パラメータ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa }; //RGBからYCCに変換しMCUに代入 void YCCTrans( EJPG *jpgc, EBMP *bmpc, int vcnt, int hcnt ){ int yy,xx,vv,uu; int j,k; int y_max,x_max; y_max=vcnt+16; x_max=hcnt+16; vv=0; uu=0; for(yy=vcnt;yyMCU[k][vv][uu] = 0.299*(double)bmpc->red[yy][xx]+0.587*(double)bmpc->green[yy][xx]+0.114*(double)bmpc->blue[yy][xx]; if(yy%2==0 && xx%2==0){ jpgc->MCU[4][vv][uu] = -0.16874*(double)bmpc->red[yy][xx]-0.33126*(double)bmpc->green[yy][xx]+0.5*(double)bmpc->blue[yy][xx]+128.0; jpgc->MCU[5][vv][uu] = 0.5*(double)bmpc->red[yy][xx]-0.41869*(double)bmpc->green[yy][xx]+0.08131*(double)bmpc->blue[yy][xx]+128.0; uu++; } if(uu==8) uu = 0; } vv = (yy%2)? vv : vv+1; } puts("YCCTrans:OK!"); } //現在はDCTのみ。MCU単位 as_selは0~3で輝度、4,5が色差 void FTTrans(EJPG *jpgc,int as_sel){ double CosinT[8][8]; double mcunit[8][8]; int cy,cx,yy,xx,vv,uu; int buf; for(yy=0;yy<8;yy++){ for(xx=0;xx<8;xx++){ CosinT[yy][xx] = cos(PAI*(double)(yy*(2*xx+1)/16)); mcunit[yy][xx] = jpgc->MCU[as_sel][yy][xx]; } } for(yy=0;yy<8;yy++){ cy=(yy==0)? 1.0 : 1/kSqrt2; for(xx=0;xx<8;xx++){ cx=(xx==0)? 1.0 : 1/kSqrt2; buf=0; for(vv=0;vv<8;vv++){ for(uu=0;uu<8;uu++){ buf += mcunit[vv][uu]*CosinT[uu][xx]*CosinT[vv][yy]; } } jpgc->MCU[as_sel][yy][xx]=buf*cy*cx/4; } } puts("FTTTrans:OK!"); } //MCU量子化 void QuantamJPG(EJPG *jpgc,int as_sel){ int yy,xx; for(yy=0;yy<8;yy++){ for(xx=0;xx<8;xx++){ if(as_sel<4) jpgc->MCU[as_sel][yy][xx] /= kYQuantumT[yy][xx]; else jpgc->MCU[as_sel][yy][xx] /= kCQuantumT[yy][xx]; } } puts("QuantamJPG:OK!"); } //ジグザグシーケンス void Zigzag(int xx[],int yy[]){ SQUARE sq; int rtl=0,i; sq.X = 0; sq.Y = 0; xx[0] = 0; yy[0] = 0; for(i=1;i<64;i++){ if(!rtl){ if(sq.Y!=0 && sq.X!=7){ sq.X++; sq.Y--; } else if(sq.Y==0 && sq.X!=7){ sq.X = sq.X + 1; rtl = 1; } else if(sq.Y==7 && sq.X==7){ rtl = 1; } else if( sq.Y!=7 && sq.X==7){ sq.Y = sq.Y + 1; rtl = 1; } else ; } else{ if(sq.X!=0 && sq.Y!=7){ sq.Y++; sq.X--; } else if(sq.X==7 && sq.Y==7){ rtl = 0; } else if(sq.X==0 && sq.Y!=7){ sq.Y = sq.Y + 1; rtl = 0; } else if(sq.X!=7 && sq.Y==7){ sq.X = sq.X + 1; rtl = 0; } else ; } xx[i]=sq.X; yy[i]=sq.Y; } puts("ZIgzag:OK!"); } //DC成分ハフマン書き込み void DCEncodeHuffman( EJPG *jpgc, int as_sel ){ int diff = (int)jpgc->MCU[as_sel][0][0] - jpgc->PreDC[as_sel]; jpgc->PreDC[as_sel] = (int)jpgc->MCU[as_sel][0][0]; int absDCdiff = abs(diff); int DCidx = 0; while(absDCdiff>0){ absDCdiff >>= 1; DCidx++; } if(as_sel<4) WriteWord(&jpgc->JPGDS,kYDcCodeT[DCidx],kYDcSizeT[DCidx]); else WriteWord(&jpgc->JPGDS,kCAcCodeT[DCidx],kCAcSizeT[DCidx]); if(DCidx){ if(diff<0) diff--; WriteWord(&jpgc->JPGDS,(DWORD)diff,DCidx); } puts("DCEncodeHuffman:OK!"); } //AC成分ハフマン書き込み void ACEncodeHuffman( EJPG *jpgc, int as_sel ){ int xx[64],yy[64]; int run,s,v,i; int absConf,ACidx; int EOBidx,ZRLidx; EOBidx = (as_sel<4)? kYEOBidx : kCEOBidx; ZRLidx = (as_sel<4)? kYZRLidx : kCZRLidx; Zigzag(xx,yy); for(i=0;i<64;i++){ absConf = abs((int)jpgc->MCU[as_sel][yy[i]][xx[i]]); if(absConf){ //ZRL書き込み while(run>15){ if(as_sel<4) WriteWord(&jpgc->JPGDS,kYAcCodeT[ZRLidx],kYAcSizeT[ZRLidx]); else WriteWord(&jpgc->JPGDS,kCAcCodeT[ZRLidx],kCAcSizeT[ZRLidx]); run -= 16; } //絶対値の係数のビット数を求める s = 0; while(absConf>0){ absConf >>= 1; s++; } //ハフマンテーブルインデックスACidxと書き込み ACidx = run*10 + s + (run==15); if(as_sel<4) WriteWord(&jpgc->JPGDS,kYAcCodeT[ACidx],kYAcSizeT[ACidx]); else WriteWord(&jpgc->JPGDS,kCAcCodeT[ACidx],kCAcSizeT[ACidx]); //係数が負のとき書き込み v = (int)jpgc->MCU[as_sel][yy[i]][xx[i]]; if(v<0) v--; WriteWord(&jpgc->JPGDS,(DWORD)v,s); //ランレングスクリア run = 0; } else{ //MCU最後にEOBを書き込む if(i==63) if(as_sel<4) WriteWord(&jpgc->JPGDS,kYAcCodeT[EOBidx],kYAcSizeT[EOBidx]); else WriteWord(&jpgc->JPGDS,kCAcCodeT[EOBidx],kCAcSizeT[EOBidx]); else run++; } } puts("ACCodeHuffman:OK!"); } void JPGHeadWriter(EJPG *jpgc,long offset,FILE *fp){ int i = 0,length; int yy[64],xx[64]; size_t s,w; BBYTE tmkr = MKR; BBYTE tsoi = SOI; BBYTE tapp0 = APP0; BBYTE tcom = COM; BBYTE tdqt = DQT; BBYTE tsof0 = SOF0; BBYTE tsos = SOS; const int ConstTable[] = {0,1,2,63,67}; int set_sof0 = 3*jpgc->JSetting.Dim+8; int set_sos = 2*jpgc->JSetting.Dim+6; s = sizeof(BBYTE); w = sizeof(BWORD); Zigzag(xx,yy); fseek(fp,offset,SEEK_SET); fwrite(&tmkr,s,1,fp); fwrite(&tsoi,s,1,fp); fwrite(&tmkr,s,1,fp); fwrite(&tapp0,s,1,fp); fwrite(&jpgc->JSetting.kJFIFL,w,1,fp); fwrite("JFIF",s,5,fp); fwrite(&jpgc->JSetting.kJFIFV,w,1,fp); fwrite(&jpgc->JSetting.units,s,1,fp); fwrite(&jpgc->JSetting.Hdens,w,1,fp); fwrite(&jpgc->JSetting.Vdens,w,1,fp); fwrite(&jpgc->JSetting.HThumbnail,s,1,fp); fwrite(&jpgc->JSetting.VThumbnail,s,1,fp); if(jpgc->JSetting.comment!=NULL){ fwrite(&tmkr,s,1,fp); fwrite(&tcom,s,1,fp); length = (int)strlen(jpgc->JSetting.comment) + 3; fwrite(&length,w,1,fp); fwrite(jpgc->JSetting.comment,s,length,fp); } fwrite(&tmkr,s,1,fp); fwrite(&tdqt,s,1,fp); fwrite(&ConstTable[4],w,1,fp); fwrite(&ConstTable[0],s,1,fp); for(i=0;i<64;i++) fwrite(&kYQuantumT[yy[i]][xx[i]],s,1,fp); fwrite(&tmkr,s,1,fp); fwrite(&tdqt,s,1,fp); fwrite(&ConstTable[4],w,1,fp); fwrite(&ConstTable[1],s,1,fp); for(i=0;i<64;i++) fwrite(&kCQuantumT[yy[i]][xx[i]],s,1,fp); fwrite(kYDcDhtT,s,kDcDhtLength,fp); fwrite(kCDcDhtT,s,kDcDhtLength,fp); fwrite(kYAcDhtT,s,kAcDhtLength,fp); fwrite(kCAcDhtT,s,kAcDhtLength,fp); fwrite(&tmkr,s,1,fp); fwrite(&tsof0,s,1,fp); fwrite(&set_sof0,w,1,fp); fwrite(&jpgc->JSetting.SamplePrecision,s,1,fp); fwrite(&jpgc->JSetting.Vsize,w,1,fp); fwrite(&jpgc->JSetting.Hsize,w,1,fp); fwrite(&jpgc->JSetting.Dim,s,1,fp); fwrite(&ConstTable[0],s,1,fp); fwrite(&kYSampleF,s,1,fp); fwrite(&ConstTable[0],s,1,fp); fwrite(&ConstTable[1],s,1,fp); fwrite(&kCSampleF,s,1,fp); fwrite(&ConstTable[1],s,1,fp); fwrite(&ConstTable[2],s,1,fp); fwrite(&kCSampleF,s,1,fp); fwrite(&ConstTable[1],s,1,fp); fwrite(&tmkr,s,1,fp); fwrite(&tsos,s,1,fp); fwrite(&set_sos,w,1,fp); fwrite(&jpgc->JSetting.Dim,s,1,fp); for(i=0;iJSetting.Dim;i++){ fwrite(&i,s,1,fp); int j = (i==0)? 0 : 0x11; fwrite(&j,s,1,fp); } fwrite(&ConstTable[0],s,1,fp); fwrite(&ConstTable[3],s,1,fp); fwrite(&ConstTable[0],s,1,fp); puts("JPEGHeadWriter:OK!"); } void BMPtoJPGEncoder(EJPG *jpgc,EBMP *bmpc){ int i,yy,xx; //出力すべきレジスタ for(yy=0;yyBMPDH.tV;yy+=16){//MCU縦の数 for(xx=0;xxBMPDH.tH;xx+=16){//MCU横の数 //RGBからYCCに変換しMCUに分け与える YCCTrans(jpgc,bmpc,yy,xx); //DCT変換 for(i=0;i<6;i++) FTTrans(jpgc,i); //量子化 for(i=0;i<6;i++) QuantamJPG(jpgc,i); for(i=0;i<6;i++){ DCEncodeHuffman(jpgc,i); ACEncodeHuffman(jpgc,i); } } } puts("BMPtoJPGEncoder:OK!"); } void JPGEncoder(EJPG *jpgc,EBMP *bmpc,long offset,FILE *fp){ BBYTE *pp = jpgc->JPGDS.buf; jpgc->JSetting.kJFIFL=16u; //JFIFバージョン長 jpgc->JSetting.kJFIFV=0x0102; //JFIFバージョン jpgc->JSetting.Dim=3u; //成分数 jpgc->JSetting.SamplePrecision=8; //サンプル精度 jpgc->JSetting.format=1; //0:不明 1:JFIF 2:JFXX jpgc->JSetting.MajorRev=1; //バージョン小数点上位 jpgc->JSetting.MinorRev=2; //バージョン小数下位 jpgc->JSetting.HThumbnail=0; //横サムネサイズ jpgc->JSetting.VThumbnail=0; //縦サムネサイズ jpgc->JSetting.CanDecode=0; //複合可能性 jpgc->JSetting.comment= "JPEG Sample by AsWe Co.,Ltd.";//コメント jpgc->JSetting.units=1; //0:単位なし 1:dots/inch 2:dots/cm jpgc->JSetting.ExtensionCode=0x10; //拡張コード 0x10:JPEG 0x11:1byte/pix 0x13:3byte/pix jpgc->JSetting.Hsize=bmpc->BMPDH.tH; //画像横サイズ jpgc->JSetting.Vsize=bmpc->BMPDH.tV; //画像縦サイズ jpgc->JSetting.Hdens=0; //横密度 jpgc->JSetting.Vdens=0; //縦密度 JPGHeadWriter(jpgc,offset,fp); BMPtoJPGEncoder(jpgc,bmpc); do{ fputc(*pp,fp); }while(*pp++); WORDMAP wm; wm.BYTE8.byte15_8 = MKR; wm.BYTE8.byte7_0 = EOI; fwrite(&wm.BYTE16.byte15_0,sizeof(BWORD),1,fp); } #endif /* ENCLIB_H_ */