// decorders.h
#include <stdio.h>
const char *ctohex( unsigned int ) ; // ※1は不要
const char *stohex( unsigned char * ) ; // バイト並びを へっくすで。
const char *stohex( unsigned char * , int ) ; // サイズ指定版
const char *check_byte_order( BYTE *pb ) ;
const char *dump_struct( FILE *fp , LPBYTE data , char *format , int total_size ) ;
const char *visdig( unsigned int c ) ;
unsigned char *digitstring_toint8( char *digstring ) ;
char *G3digits( unsigned char sig ) ;
DWORD G3MHasBITSTR1728( char *dest , char *src , int size_dest ) ;
const char *visdig( unsigned int c )
{
// visualize as digits
#define UNIT_BUFF 33 // 32 + '1' for null termaination. 33 is for future's insurance.
static char ret[UNIT_BUFF * 8] ; // 8 回まで同時可。printf などで同時に使うことはたまに良くある。
static char bctr ;
char *pret ;
pret = ret + UNIT_BUFF * bctr ;
int ctr ;
for( ctr = 0 ; ctr < 8 ; ctr ++ , pret ++ )
{ if( c & ( 0x1 << ctr ) )
*pret = '1' ;
else *pret = '0' ;
}
*pret ++= '\0' ;
bctr ++ ;
if( bctr & 8 ) bctr = 0 ; // i.e bctr == 8 ;
pret += 24 ;
return pret - UNIT_BUFF ;
#undef UNIT_BUFF
}
unsigned char *digitstring_toint8( char *digstring )
{
unsigned int uiresult = 0 ;
static unsigned char retbuf[4096] ;
unsigned char *lpbuf = retbuf ;
int count ; unsigned int mask ;
for( count = 0 , mask = 0x1 ; *digstring
; ( count == 7 ) ? count = 0 : count ++ , digstring ++ , count ? mask <<= 1 : mask = 0x1 )
{
if( *digstring == '0' ) ;
else
uiresult |= mask ;
if( count == 7 ) {
*lpbuf ++ = uiresult & 0xFF ;
uiresult = 0 ;
}
}
if( count ) *lpbuf ++ = uiresult & 0xFF ;
*lpbuf = '\0' ;
return retbuf ;
}
char *G3digits( unsigned char sig )
{
#define EASYCODE( x , disp ) case (x) : return #disp
switch( sig )
{
EASYCODE( 0 + 4 + 128 , CFR0 ) ;
EASYCODE( 1 + 4 + 128 , CFR1 ) ;
EASYCODE( 1 + 64 , CIG ) ;
EASYCODE( 0 + 2 + 8 + 16 , CRP0 ) ;
EASYCODE( 1 + 2 + 8 + 16 , CRP1 ) ;
EASYCODE( 64 , CSI ) ;
EASYCODE( 0 + 2 + 16 , CTC0 ) ;
EASYCODE( 1 + 2 + 16 , CTC1 ) ;
EASYCODE( 0+4+64+128 , CTR0) ;
EASYCODE( 1+4+64+128 , CTR1) ;
EASYCODE( 0+2+8+16+32+64+128 , DCN0) ;
EASYCODE( 1+2+8+16+32+64+128 , DCN1) ;
EASYCODE( 0+2+128 , DCS0) ;
EASYCODE( 1+2+128 , DCS1) ;
EASYCODE( 128 , DIS) ;
EASYCODE( 1+128 , DTC) ;
EASYCODE( 0+2+4+8+128 ,EOM0 ) ;
EASYCODE( 1+2+4+8+128 ,EOM1 ) ;
EASYCODE( 0+2+4+8+32 , EOP0) ;
EASYCODE( 1+2+4+8+32 , EOP1) ;
EASYCODE( 0+2+4+8+64+128 , EORr0) ;
EASYCODE( 1+2+4+8+64+128 , EORr1) ;
EASYCODE( 0+4+8+16 , ERR0 ) ;
EASYCODE( 1+4+8+16 , ERR1 ) ;
EASYCODE( 0+4+8+16+32+64+128 , FDM0) ;
EASYCODE( 1+4+8+16+32+64+128 , FDM1) ;
EASYCODE( 0+4+64 , FTT0) ;
EASYCODE( 1+4+64 , FTT1) ;
EASYCODE( 0+4+8+128 , MCF0) ;
EASYCODE( 1+4+8+128 , MCF1) ;
EASYCODE( 0+2+4+8+64 , MPS0) ;
EASYCODE( 1+2+4+8+64 , MPS1) ;
EASYCODE( 1+32 , NSC ) ;
EASYCODE( 32 , NSF ) ;
EASYCODE( 0+2+32 , NSS0) ;
EASYCODE( 1+2+32 , NSS1) ;
EASYCODE( 0 , NULL ) ;
EASYCODE( 0+4+8+32 , PIN0) ;
EASYCODE( 1+4+8+32 , PIN1) ;
EASYCODE( 0+4+8+32+128 , PIP0) ;
EASYCODE( 1+4+8+32+128 , PIP1) ;
EASYCODE( 0+4+8+16+32+128 , PPR0) ;
EASYCODE( 1+4+8+16+32+128 , PPR1) ;
EASYCODE( 0+2+4+8+16+32+128 , PPSr0) ;
EASYCODE( 1+2+4+8+16+32+128 , PPSr1) ;
EASYCODE( 0+2+4+8+16+128 , PRI_EOM0) ;
EASYCODE( 1+2+4+8+16+128 , PRI_EOM1) ;
EASYCODE( 0+2+4+8+16+32 , PRI_EOP0) ;
EASYCODE( 1+2+4+8+16+32 , PRI_EOP1) ;
EASYCODE( 0+2+4+8+16+64 , PRI_MPS0) ;
EASYCODE( 1+2+4+8+16+64 , PRI_MPS1) ;
EASYCODE( 1+ 64+128 , PWD_TX ) ;
EASYCODE( 0+2+64+128 ,PWD_RX0 ) ;
EASYCODE( 1+2+64+128 ,PWD_RX1 ) ;
EASYCODE( 0+4+8+32+64+128 , RNR0) ;
EASYCODE( 1+4+8+32+64+128 , RNR1) ;
EASYCODE( 0+2+4+8+32+64 , RR0) ;
EASYCODE( 1+2+4+8+32+64 , RR1) ;
EASYCODE( 0+4+8+64 , RTN0) ;
EASYCODE( 1+4+8+64 , RTN1) ;
EASYCODE( 0+4+8+64+128 , RTP0) ;
EASYCODE( 1+4+8+64+128 , RTP1) ;
EASYCODE( 1+ 32+128 , SEP) ;
EASYCODE( 1 , _SOH_) ;
EASYCODE( 2 , _STX_) ;
EASYCODE( 3 , _ETX_) ;
EASYCODE( 4 , _EOT_) ;
EASYCODE( 16, _DLE_) ;
// EASYCODE( 0+2+64+128 , SUB0) ; // same as PWD_RX0,1
// EASYCODE( 1+2+64+128 , SUB1) ;
EASYCODE( 2+4 , FCD ) ;
default : break ;
}
return "?" ;
#undef ES
}
// Table 1
// Terminating Codes
// run length white code black code
struct ICPCP { int idx ; char *white ; char *black ; } ;
#define W_str(x) ( ((x)<64)? MHtable[(x)].white : MHtable[63+( (0x40 -1)&((x)>>6))].white )
#define B_str(x) ( ((x)<64)? MHtable[(x)].black : MHtable[63+( (0x40 -1)&((x)>>6))].black )
#define W_remainder( x) (((x)<64 /*|| ( (!((x)&(0x40-1)))&& ((x)%320) )*/ ) ? "" : MHtable[((x)&(0x40-1))].white )
#define B_remainder( x) (((x)<64 /*|| ( (!((x)&(0x40-1)))&& ((x)%320) )*/ ) ? "" : MHtable[((x)&(0x40-1))].black )
//w0b1728 が成功する以上、これでよいはず。
// where 'x' is equal to "runlength" .
ICPCP MHtable[124] =
{
{0 , "00110101" , "0000110111"},
{1 , "000111" , "010"},
{2 , "0111" , "11"},
{3 , "1000" , "10"},
{4 , "1011" , "011"},
{5 , "1100" , "0011"},
{6 , "1110" , "0010"},
{7 , "1111" , "00011"},
{8 , "10011" , "000101"},
{9 , "10100" , "000100"},
{10, "00111" , "0000100"},
{11, "01000" , "0000101"},
{12, "001000" , "0000111"},
{13, "000011" , "00000100"},
{14, "110100" , "00000111"},
{15, "110101" , "000011000"},
{16, "101010" , "0000010111"},
{17, "101011" , "0000011000"},
{18, "0100111" , "0000001000"},
{19, "0001100" , "0000" "1" "100111" }, // 00001100111 ? YES !
{20, "0001000" , "00001101000"},
{21, /**/ "0010111" , "00001101100"}, // 001011?
{22, "0000011" , "00000110111"},
{23, "0000100" , "00000101000"},
{24, "0101000" , "00000010111"},
{25, "0101011" , "00000011000"},
{26, "0010011" , "000011001010"},
{27, "0100100" , "000011001011"},
{28, "0011000" , "000011001100"},
{29, "00000010" , "000011001101"},
{30, "00000011" , "000001101000"},
{31, "00011010" , "000001101001"},
{32, "00011011" , "000001101010"},
{33, "00010010" , "000001101011"},
{34, "00010011" , "000011010010"},
{35, "00010100" , "000011010011"},
{36, "00010101" , "000011010100"},
{37, "00010110" , "000011010101"},
{38, "00010111" , "000011010110"},
{39, "00101000" , "000011010111"},
{40, "00101001" , "000001101100"},
{41, "00101010" , "000001101101"},
{42, "00101011" , "000011011010"},
{43, "00101100" , "000011011011"},
{44, "00101101" , "000001010100"},
{45, "00000100" , "000001010101"},
{46, "00000101" , "000001010110"},
{47, "00001010" , "000001010111"},
{48, "00001011" , "000001100100"},
{49, "01010010" , "000001100101"},
{50, "01010011" , "000001010010"},
{51, "01010100" , "000001010011"},
{52, "01010101" , "000000100100"},
{53, "00100100" , "000000110111"},
{54, "00100101" , "000000111000"},
{55, "01011000" , "000000100111"},
{56, "01011001" , "000000101000"},
{57, "01011010" , "000001011000"},
{58, "01011011" , "000001011001"},
{59, "01001010" , "000000101011"},
{60, "01001011" , "000000101100"},
{61, "00110010" , "000001011010"},
{62, "00110011" , "000001100110"},
{63, "00110100" , "000001100111"},
// 64
// Make-up Codes
// run length white code black code
{64 , "11011" , "000000111" "1"},
{128 , "10010" , "000011001000"},
{192 , "010111" , "000011001001"},
{256 , "0110111" , "000001011011"},
{320 , "00110110" , "000000110011"},
{384 , "00110111" , "000000110100"},
{448 , "01100100" , "000000110101"},
{512 , "01100101" , "0000001101100"},
{576 , "01101000" , "0000001101101"},
{640 , "01100111" , "0000001001010"},
{704 , "011001100", "0000001001011"},
{768 , "011001101", "0000001001100"},
{832 , "011010010", "0000001001101"},
{896 , "011010011", "0000001110010"},
{960 , "011010100", "0000001110011"},
{1024, "011010101", "0000001110100"},
{1088, "011010110", "0000001110101"},
{1152, "011010111", "0000001110110"},
{1216, "011011000", "0000001110111"},
{1280, "011011001", "0000001010010"},
{1344, "011011010", "0000001010011"}, /**/
{1408, "011011011", "0000001010100"},
{1472, "010011000", "0000001010101"},
{1536, "010011001", "0000001011010"},
{1600, "010011010", "0000001011011"},
{1664, "011000" , "0000001100100"},
{1728, "010011011", "0000001100101"},
// 37
//Extended Make-up codes (white + black)
{1792, "00000001000" , ""},
{1856, "00000001100" , ""},
{1920, "00000001101" , ""},
{1984, "000000010010", ""},
{2048, "000000010011", ""},
{2112, "000000010100", ""},
{2176, "000000010101", ""},
{2240, "000000010110", ""},
{2304, "000000010111", ""},
{2368, "000000011100", ""},
{2432, "000000011101", ""},
{2496, "000000011110", ""},
{2560, "000000011111", ""},
// 23
} ;
DWORD G3MHasBITSTR1728( char *dest , char *src , int size_dest )
{ // "00011101010000..." ビットマップ( 文字の '0' と '1' ) で構成された絵。
// => "省略" G3 FAx の MH コード化を施したもの。'0' と '1' で構成された文字列の形。
// == バイナリ形式を、文字列の形に可視化したもの。!! 本当の意味でのバイナリ形式には、各自あとでする。
int pixline = 1728 ; int iscan = 0 ;
char *dest_ = dest ;
int mode = 0x0 ;
int ctctr = 0 ;
//if( *src != '0' ) { dest = stpcpy( dest , W_str(1) ) ;
//src ++ ; iscan ++ ; ctctr = 1 ; }
if( *src != '0' ) dest = stpcpy( dest , W_str(0) ) ;
for( ; dest - dest_ < size_dest && iscan <= pixline ;
src ++ , iscan ++ )
{
if( ! *src || pixline == iscan ) mode |= 0x2 ;
else
if( *src == '0' )
{ if( ! ( mode & 0x1 )) ctctr ++ ;
else mode |= 0x2 ;
}
else
{ if( mode & 0x1 ) ctctr ++ ;
else mode |= 0x2 ;
}
if( mode & 0x2 )
{ mode &= ~0x2 ;
if( ! (mode & 0x1) ) // 白
{ dest = stpcpy( dest , W_str(ctctr)) ;
dest = stpcpy( dest , W_remainder(ctctr)) ;
}
else // 黒
{ dest = stpcpy( dest , B_str(ctctr)) ;
dest = stpcpy( dest , B_remainder(ctctr)) ;
}
mode ^= 0x1 ; ctctr = 1 ;
}
if( ! *src ) { iscan ++ ; break ; }
}
if( iscan != ( pixline +1 ) )
{ // 正常に終われば pixline + 1 == iscan のはずである。
if( ! *src && iscan < pixline + 1 )
{ int ctremain = pixline - iscan ; // 少々ややこしいがこうなる。
// この場合黒で埋める。
dest = stpcpy( dest , B_str( ctremain )) ;
dest = stpcpy( dest , B_remainder( ctremain )) ;
}
}
if( *src ) *stpcpy( dest ,
"00110101" "00000011" "00101" "000" "00000000" ) = '\0' ;
// エラー(1728以上のピクセル。)の場合、一行全部黒線の w0b1728 ( W_str(0) + B_str(1728) )
return 1 ;
}