JpgToBmp

来源:互联网 发布:java工程师个人技能 编辑:程序博客网 时间:2024/06/15 23:47


#include <stdio.h>
#include <alloc.h>
#include <math.h>
#define PI 3.1415927
#define widthbytes(i) ((i + 31) / 32 * 4 )
int sampleYH, sampleYV, sampleUH, sampleUV, sampleVH, sampleVV;
int HYtoU, VYtoU, HYtoV, VYtoV;
int YinMCU, UinMCU, VinMCU;
int compressnum = 0, Qt[3][64], codepos[4][16], codelen[4][16];
int *YQt, *UQt, *VQt ;
unsigned char compressindex[3], YDCindex, YACindex, UVDCindex, UVACindex;
unsigned char HufTabindex, And[9] = {0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff};
unsigned int codevalue[4][256], hufmax[4][16], hufmin[4][16];
int bitpos = 0, curbyte = 0, run = 0, value = 0, MCUbuffer[10 * 64], blockbuffer[64];
int ycoef = 0, ucoef = 0, vcoef = 0, intervalflag = 0, interval = 0, restart = 0;
long Y[4 * 64], U[4 * 64], V[4 * 64], QtZMCUbuffer[10 * 64];
unsigned long imgwidth = 0, imgheight = 0, width =0, height = 0, linebytes;
int Z[8][8] = {{0, 1, 5, 6, 14, 15, 27, 28},
               {2, 4, 7, 13, 16, 26, 29, 42},
               {3, 8, 12, 17, 25, 30, 41, 43},
               {9, 11, 18, 24, 31, 40, 44, 53},
               {10, 19, 23, 32, 39, 45, 52, 54},
               {20, 22, 33, 38, 46, 51, 55, 60},
               {21, 34, 37, 47, 50, 56, 59, 61},
               {35, 36, 48, 49, 57, 58, 62, 63}};


struct{
       unsigned char type[2] ;
       long size ;
       long reserved ;
       long offset ;      
       }head;

struct{
       long size ;
       long width ;
       long height ;
       int plane ;
       int bitcount ;
       long compression ;
       long imagesize ;
       long xpels ;
       long ypels ;
       long colorused ;
       long colorimportant ;
       }bmp ;
    
void error(char * s)
{
     printf("%s/n", s) ;
     exit(1) ;   
     }      
    
   
void initialize( FILE * fp )
{
     unsigned char *p, *q,  hfindex, qtindex, number ;
     int i, j, k, finish =0, huftab1, huftab2, huftabindex, count ;
     unsigned int length, flag ;
     fread(& flag, sizeof(unsigned int), 1, fp) ; 
     if(flag != 0xd8ff)   /*SOI wrong 匹配SOI*/
         error("Error Jpg File format SOI !") ;
     while(! finish)
     {
          fread(& flag, sizeof(unsigned int), 1, fp) ; /*读取标记头*/
          fread(&length, sizeof(unsigned int), 1, fp) ;
          length = ((length << 8) | (length >> 8)) - 2 ; /*读取段长度  高低位调整*/
          switch(flag)
          {
           case 0xe0ff:   /*APPO 段*/
                fseek(fp, length, 1) ;
                break ;
           case 0xdbff:   /* DQT */
                p = malloc(length) ;
                fread(p, length, 1, fp) ; /* P指向(Pq,Tq) 共一个字节 Pq表精度 Tq表示 量化表编号 */
                qtindex = (* p) & 0x0f ;  /* 求Tq 用低四 */
                q = p + 1 ;              /* 量化表中第一个值 之字形排列 */
                if(length + 2 <80)       /* 量化表个数为1时 */
                    for(i = 0; i < 64; i ++)
                        Qt[qtindex][i] = (int) * (q ++) ;
                else{
                    for(i = 0; i < 64; i ++)
                        Qt[qtindex][i] = (int) * (q ++) ;
                    qtindex = * (q ++ ) & 0x0f ; /* 求第二个量化表编号 */
                    for(i = 0; i < 64; i ++)
                        Qt[qtindex][i] = (int) * (q ++) ;
                     }
                free(p) ;
                break ;
           case 0xc0ff:    /* Start of Frame */
                p = malloc(length) ;
                fread(p, length, 1, fp) ;  /* P指向SOF中 P */
                imgheight = ((* (p + 1)) << 8) + (* (p + 2)) ; /* 图像高度  需要交换字节高低位顺序 */
                imgwidth = ((* (p + 3)) << 8) + (* (p + 4)) ;
                compressnum = * (p + 5) ;   /* Frame 中成分个数 1代表灰度图  3代表真彩图 */
                if((compressnum != 1) && (compressnum != 3))
                    error("Error Jpg File format SOF !") ;
                if(compressnum == 3)
                {
                    compressindex[0] = * (p + 6) ;   /* Frame 成份 */
                    sampleYH = (* (p + 7)) >> 4 ;   /* 对应成分水平取样因子 */
                    sampleYV = (* (p + 7)) & 0x0f ; /* 垂直取样因子 */
                    YQt = (int *) Qt[* (p + 8)] ;   /* Y量化表编号 */
                    compressindex[1] = * (p + 9) ;  /* 第二个成分 */
                    sampleUH = (*(p + 10)) >> 4 ;
                    sampleUV = (* (p + 10)) & 0x0f ;
                    UQt = (int *) Qt[* ( p + 11)] ;
                    compressindex[2] = * (p + 12) ;
                    sampleVH = (*(p + 13)) >> 4 ; 
                    sampleVV = (* (p + 13)) & 0x0f ;
                    VQt = (int *) Qt[* (p + 14)] ;    /* V成分量化表编号 */
                    }
                else    /* 灰度图像时 */
                {
                    compressindex[0] = * (p + 6) ;
                    sampleYH = (* (p + 7)) >> 4 ;
                    sampleYV = (* (p + 7)) & 0x0f ;
                    YQt = (int *) Qt[* (p + 8)] ;
                    compressindex[1] = * (p + 6) ;
                    sampleUH = 1 ;    /* U V 成分无效 */
                    sampleUV = 1;
                    UQt = (int *) Qt[* (p + 8)] ;
                    compressindex[2] = * (p + 6) ;
                    sampleVH = 1 ;
                    sampleVV = 1;
                    VQt = (int *) Qt[* (p + 8)] ;
                    }
                free(p) ;
                break ;
           case 0xc4ff:   /* DHT 段 */
                p = malloc(length + 1) ;
                fread(p, length,1, fp) ;  /* P指向(Tc,Th)Tco 0rxj DC用HUF表 为1 指AC用HUF表 */
                p[length] = 0xff ;    /* 结尾标识 */
                if(length + 2 < 0xd0)    /* 只有一个DHT表时*/
                {
                    huftab1 = (int) (*p) >> 4 ; /* huftab1 = Tc */
                    huftab2 = (int) (*p) & 0x0f ; /* huftab2 = Th */
                    huftabindex = huftab1 *2 + huftab2 ;  /* huf表编号 */
                    q = p + 1 ;
                    for(i = 0; i < 16; i ++)
                        codelen[huftabindex][i] = (int) (* (q ++)) ;/* 第i字节表示了i位长的 Huffman代码的个数(i= 1到16)*/
                    j = 0 ; 
                    for(i = 0; i < 16; i ++)   
                        if(codelen[huftabindex][i] != 0)
                        {
                            k = 0 ;
                            while(k < codelen[huftabindex][i]) /*提取codelen[huftabindex][i]个i位长度编码*/
                            {
                                codevalue[huftabindex][k + j] = (int) (* (q ++)) ;/* 编码值*/
                                k ++ ;  
                                } /*end while */
                             j += k ;   /* 表的长度 (字节数) = 这 16 个数字之和*/
                            }  /* end if  */
                    i = 0 ;
                    while(codelen[huftabindex][i] == 0) /* 长度为i的编码没有*/
                        i ++ ;
                    for(j = 0; j < i; j ++)  
                    {
                        hufmin[huftabindex][j] = 0 ;    /* i位长度没有编码则编码最小值和最大值都置0 */
                        hufmax[huftabindex][j] = 0 ; 
                        }  /*end for */
                     hufmin[huftabindex][i] = 0 ;   /* 编码最小值从0开始 */
                     hufmax[huftabindex][i] = codelen[huftabindex][i] - 1 ;  /* 最大值与最小值的差值用hufmax 表示*/
                     for(j = i + 1; j < 16; j ++)
                     {
                         hufmin[huftabindex][j] = (hufmax[huftabindex][j - 1] + 1) << 1 ; /* 计算i位长度编码值 f(i)=2*(f(i-1)+1)*/
                         hufmax[huftabindex][j] = hufmin[huftabindex][j] + codelen[huftabindex][j] - 1 ; /* i位编码的最大编码值*/
                         }  /* end ofr */
                     codepos[huftabindex][0] = 0 ;  /* 编码值位置 */
                     for(j = 1; j < 16; j ++)
                         codepos[huftabindex][j] = codelen[huftabindex][j - 1] + codepos[huftabindex][j - 1] ; /* 前一编码位置+前一编码位长度 */             
                     }
                else
                {
                    hfindex = * p ;
                    while(hfindex != 0xff)
                    {
                        huftab1 = (int) hfindex >> 4 ;  /* huftab1 = Tc */
                        huftab2 = (int) hfindex & 0x0f ;  /* huftab2 = Th */
                        huftabindex = huftab1 *2 + huftab2 ;  /* huf表编号 */
                        q = p + 1 ;
                        count = 0 ;
                        for(i = 0; i < 16; i ++)
                        {
                            codelen[huftabindex][i] = (int) (* (q ++)) ;
                            count += codelen[huftabindex][i] ;   /* 表的字节长度 */
                            } /* end for    */
                        count += 17 ;    /* Tc  Th  及16个长度的字节 共17字节*/
                        j = 0 ;
                        for(i = 0; i < 16; i ++)
                            if(codelen[huftabindex][i] != 0)        /* 以下内容同上处一个表时的处理*/
                            {
                                k = 0 ;
                                while(k < codelen[huftabindex][i])
                                {
                                    codevalue[huftabindex][k + j] = (int) (* (q ++)) ;
                                    k ++ ;
                                    } /*end while */
                                j += k ;   
                                } /*end if  */
                        i = 0 ;
                        while(codelen[huftabindex][i] == 0)
                            i ++ ;
                        for(j = 0; j < i; j ++)
                        {
                            hufmin[huftabindex][j] = 0 ;
                            hufmax[huftabindex][j] = 0 ;
                            } /*end for   */
                        hufmin[huftabindex][i] = 0 ;
                        hufmax[huftabindex][i] = codelen[huftabindex][i] - 1 ;
                        for(j = i + 1; j < 16; j ++)
                        {
                            hufmin[huftabindex][j] = (hufmax[huftabindex][j - 1] + 1) << 1 ;
                            hufmax[huftabindex][j] = hufmin[huftabindex][j] + codelen[huftabindex][j] - 1 ;
                            } /*end for */
                        codepos[huftabindex][0] = 0 ;
                        for(j = 1; j < 16; j ++)
                            codepos[huftabindex][j] = codelen[huftabindex][j - 1] + codepos[huftabindex][j - 1] ;
                        p += count ;   /*  p偏移至下一DHT表*/
                        hfindex = * p ;       
                        } /* end while   */
                    p -= length ;
                    }  /*end else   */
              free(p) ;
              break ;
          case 0xddff:   /* DRI 段 */
               p = malloc(length) ;
               fread(p, length, 1, fp) ;
               restart = ((* p) << 8) | (* (p + 1)) ;   /* MCU个数 字节顺序调整得结果 */
               free(p) ;
               break ;
          case 0xdaff:   /* start of scan 段 */
               p = malloc(length * sizeof(unsigned char)) ;
               fread(p, length, 1, fp) ;
               number = * p ; /* Frame中成分的个数Ns */
               if(number != compressnum)
                   error("Error Jpg File format here !") ;
               q = p + 1 ;   /* q为成分编号Csn */
               for(i = 0; i <compressnum; i ++)
               {
                   if(* q == compressindex[0]) /* 成分编号对应Y成分 */
                   {
                       YDCindex = (* (q + 1)) >> 4 ; /* Y成分DC编码表编号为YDCindex=Tdn */
                       YACindex = ((* (q + 1)) & 0x0f) + 2 ;  /* Y成分AC编码表编号 */
                       } /* end if  */ 
                   else
                   {
                       UVDCindex = (* (q + 1)) >> 4 ;   /* U V DC编码表编号 */
                       UVACindex = ((* (q + 1)) & 0x0f) + 2 ;
                       }  /*end else*/
                   q += 2 ;
                   } /* end for  */
               finish = 1 ;
               free(p) ; 
               break ;
          case 0xd9ff:  /* EOI */
               error("Error Jpg File format EOI !") ;
               break ;
          default:
               if((flag & 0xf000) != 0xd000)
                   fseek(fp, length, 1) ;
               break ;                              
          } /*end switch   */    
     } /*end while  */     
} /* end initialize   */


void makebmpheader(FILE * fp)
{
     int i, j ;
     unsigned long colorbits = 24, imagebytes ;
     linebytes = widthbytes(colorbits * imgwidth) ;
     imagebytes = (unsigned long) imgheight * linebytes ;
     head.type[0] = 'B' ;
     head.type[1] = 'M' ;
     head.size = imagebytes + 0x36 ;
     head.reserved = 0;
     head.offset = 0x36 ;
     fwrite(& head, sizeof(head), 1, fp) ;
     bmp.size = 0x28 ;  /*  40 bytes   */
     bmp.width = (long) imgwidth ;
     bmp.height = (long) imgheight ;
     bmp.plane = 1L ;  /* 规定为1  */
     bmp.bitcount = colorbits ;
     bmp.compression = 0 ;
     bmp.imagesize = imagebytes ;
     bmp.xpels = 0xece ;  /*????????????  */
     bmp.ypels = 0xec4 ;
     bmp.colorused = 0;
     bmp.colorimportant = 0 ;
     fwrite(&bmp, sizeof(bmp), 1, fp) ;
     for(j = 0; j < imgheight; j ++ )
     for(i = 0; i < linebytes; i ++ )      /*先全部置数据为0*/
         fputc(0, fp) ;
     }
    
        
void idct(long *p, int k)
{
    long x, x0, x1, x2, x3, x4, x5, x6, x7 ;
    x1 = p[k * 4] << 1 ;
    x2 = p[k * 6] ;
    x3 = p[k * 2] ;
    x4 = p[k * 1] ;
    x5 = p[k * 7] ;
    x6 = p[k * 5] ;
    x7 = p[k * 3] ;
    x0 = (p[0] << 11) + 1024 ;
    x= 565 * (x4 + x5) ;
    x4 = x + 2276 * x4;
    x5 = x- 3406 * x5 ;
    x = 2408 * (x6 + x7) ;
    x6 = x- 799 * x6 ;
    x7 = x- 4017 * x7 ;
    x = 1108 * (x3 + x2) ;
    x2 = x- 3784 * x2 ;
    x3 = x+ 1568 * x3 ;
    x = x6 ;
    x6 = x5 + x7 ;
    x5 -= x7 ;
    x7 = x0 + x1 ;
    x0 -= x1 ;
    x1 = x + x4 ;
    x4 -= x ;
    x = x5 ;
    x5 = x7 - x3;
    x7 += x3 ;
    x3 = x0 + x2 ;
    x0 -= x2 ;
    x2 = ( 181 * (x4 + x) + 128) >> 8 ;
    x4 = (181 * (x4 - x) + 128) >> 8 ;
    p[0] = (x7 + x1) >> 11 ;
    p[k * 1] = (x3 + x2) >> 11 ;
    p[k * 2] = (x0 + x4) >> 11 ;
    p[k * 3] = (x5 + x6) >> 11 ;
    p[k * 4] = (x5 - x6) >> 11 ;
    p[k * 5] = (x0 - x4) >> 11 ;
    p[k * 6] = (x3 - x2) >> 11 ;
    p[k * 7] = (x7 - x1) >> 11 ;
    } /* end idct  */
   
   

void IDCTint(long * metrix)
{
    int i ;
    for(i= 0; i < 8; i ++)
        idct(metrix + 8 * i, 1) ;
    for(i = 0; i< 8; i ++)
        idct(metrix + i, 8) ;
    }/* end IDCTint */


void IQtZBlock(int *s, long *d, int *pQt, int correct)
{
    int i, j, tag ;
    long *pbuffer, buffer[8][8] ;
    for(i = 0; i < 8; i ++)
    for(j = 0; j < 8; j ++)
    {
        tag = Z[i][j] ;
        buffer[i][j] = (long) s[tag] * (long) pQt[tag] ;
        }/* end for */
    pbuffer = (long *) buffer ;
    IDCTint(pbuffer) ;
    for(i = 0; i < 8; i ++)
    for(j = 0; j < 8; j ++)
        d[i * 8 + j] = (buffer[i][j] >> 3) + correct ;
    } /* end IQtBlock */


void IQtZMCU(int xx, int yy, int offset, int *pQt, int correct)
{
    int i, j, *pMCUBuffer ;
    long *pQtZMCUBuffer ;
    pMCUBuffer = MCUbuffer + offset ;
    pQtZMCUBuffer = QtZMCUbuffer + offset ;
    for(i = 0; i < yy; i ++)
    for(j = 0; j < xx; j ++)
    IQtZBlock(pMCUBuffer + (i * xx + j) * 64, pQtZMCUBuffer + (i * xx + j) * 64, pQt, correct) ;
    } /* end IQtZMCU  */

    
void getYUV(int xx, int yy, long *buf, int offset)
{
    int i, j, k, n ;
    long *pQtZMCU ;
    pQtZMCU = QtZMCUbuffer + offset ;
    for(i = 0; i < yy; i ++)
    for(j = 0; j < xx; j ++)
    for(k = 0; k < 8; k ++)
    for(n = 0; n < 8; n ++)
    buf[(i * 8 + k) * sampleYH * 8 + j * 8 + n] = *pQtZMCU ++ ;
    } /* end getYUV */


void savebmp(FILE *fp)
{
    int i, j ;
    unsigned char r, g, b;
    long y, u, v, rr, gg, bb ;
    for(i = 0; i < sampleYV * 8; i ++)
    {
        if((height + i) < imgheight)
        {
            fseek(fp, (unsigned long) (imgheight - height - i - 1) * linebytes + 3 * width + 54, 0) ;
            for(j = 0; j < sampleYH * 8; j ++)
            {
                if((width + j) < imgwidth)
                {
                    y = Y[i * 8 * sampleYH + j] ;
                    u = U[(i / VYtoU) * 8 * sampleYH + j / HYtoU] ;
                    v = V[(i / VYtoV) * 8 * sampleYH + j / HYtoV] ;
                    rr = ((y << 8) + 359 * v) >> 8 ;
                    gg = (( y << 8) - 88 * u - 183 * v) >> 8 ;
                    bb = (( y << 8) + 301 * u) >> 8 ;
                    r = (unsigned char) rr ;
                    g = (unsigned char) gg ;
                    b = (unsigned char) bb ;
                    if(rr & 0xffffff00)
                    if(rr > 255)
                        r = 255 ;
                    else if(rr < 0)
                        r = 0 ;
                    if(gg & 0xffffff00)
                    if(gg > 255)
                        g = 255 ;
                    else if(gg < 0)
                        g = 0 ;
                    if(bb & 0xffffff00)
                    if(bb > 255)
                        b = 255 ;
                    else if(bb < 0)
                        b = 0 ;
                    fputc(b, fp) ;
                    fputc(g, fp) ;
                    fputc(r, fp) ;
                    } /* end if  */
                else
                    break ;
                } /* end for  */
            } /* end if   */
        else
            break ;
        } /* end for */
    } /* end savebmp  */
   

void decode(FILE *fp1, FILE *fp2)
{
    int Yinbuf, Uinbuf, Vinbuf ;
    YinMCU = sampleYH * sampleYV ; /* y 分量在MCU中数据单元个数 数据单元 8*8阵*/
    UinMCU = sampleUH * sampleUV ;
    VinMCU = sampleVH * sampleVV ; /* v 分量在MCU中数据单元个数*/
    HYtoU = sampleYH / sampleUH ;  /* 水平方向y:u */
    VYtoU = sampleYV / sampleUV ;  /* 垂直方向y:u */
    HYtoV = sampleYH / sampleVH ;  /* 水平方向y:v */
    VYtoV = sampleYH / sampleVV ;
    Yinbuf = 0 ;
    Uinbuf = YinMCU * 64 ; /* U分量在 MCU 中样点 */
    Vinbuf = (YinMCU + UinMCU) * 64 ;
    while(DecodeMCUBlock(fp1))
    {
        interval ++ ;
        if((restart) && (interval % restart == 0))
            intervalflag = 1 ;
        else
            intervalflag = 0 ;
        IQtZMCU(sampleYH, sampleYV, Yinbuf, YQt, 128) ;
        IQtZMCU(sampleUH, sampleUV, Uinbuf, UQt, 0) ;
        IQtZMCU(sampleVH, sampleVV, Vinbuf, VQt, 0) ;       
        getYUV(sampleYH, sampleYV, Y, Yinbuf) ;
        getYUV(sampleUH, sampleUV, U, Uinbuf) ;
        getYUV(sampleVH, sampleVV, V, Vinbuf) ;
        savebmp(fp2) ;
        width += sampleYH * 8 ;
        if(width >= imgwidth)
        {
            width = 0;
            height += sampleYV * 8 ;
            } /* end if  */
        if((width == 0) && (height >= imgheight))
            break ;
        } /*end while */
    } /* end decode */


int HufBlock(FILE *fp, unsigned char dchufindex, unsigned char achufindex)
{
    int i, count = 0 ;
    HufTabindex = dchufindex ;
    if(DecodeElement(fp) != 1)
        return 0 ;
    blockbuffer[count ++] = value ;
    HufTabindex = achufindex ;
    while(count < 64)
    {
        if(DecodeElement(fp) != 1)
            return 0 ;
        if((run == 0) && (value == 0))
        {
            for(i = count; i < 64; i ++)
                blockbuffer[i] = 0 ;
            count = 64 ;
            } /* end if  */
        else
        {
            for(i = 0; i < run; i ++)
                blockbuffer[count ++] = 0 ;
            blockbuffer[count ++] = value ;
            } /* end else */
        } /* end while  */
    return 1 ;
    } /* end HufBlock */ 
   
 
int DecodeMCUBlock(FILE *fp)
{
    int i, j, *pMCUBuffer ;
    if(intervalflag)
    {
        fseek(fp, 2, 1) ;
        ycoef = ucoef = vcoef = 0 ;
        bitpos = 0;
        curbyte = 0 ;
        } /* end if  */
    switch(compressnum){
        case 3:
             pMCUBuffer = MCUbuffer ;
             for(i = 0; i < sampleYH * sampleYV; i ++)
             {
                 if(HufBlock(fp, YDCindex, YACindex) != 1)
                     return 0 ;
                 blockbuffer[0] += ycoef ;
                 ycoef = blockbuffer[0] ;
                 for(j = 0; j < 64; j++)
                     *pMCUBuffer ++ = blockbuffer[j] ;
                 } /* end for */
             for(i = 0; i < sampleUH * sampleUV; i++)
             {
                 if(HufBlock(fp, UVDCindex, UVACindex) != 1)
                     return 0 ;
                 blockbuffer[0] += ucoef ;
                 ucoef = blockbuffer[0] ;
                 for(j = 0; j < 64; j++)
                     *pMCUBuffer ++ = blockbuffer[j] ;
                 } /* end for */
             for(i = 0; i < sampleVH * sampleVV; i ++)
             {
                 if(HufBlock(fp, UVDCindex, UVACindex) != 1)
                     return 0 ;
                 blockbuffer[0] += vcoef ;
                 vcoef = blockbuffer[0] ;
                 for(j = 0; j < 64; j ++)
                     *pMCUBuffer ++ = blockbuffer[j] ;
                 } /* end for*/
             break ;
        case 1:
             pMCUBuffer = MCUbuffer ;
             if(HufBlock(fp, YDCindex, YACindex) != 1)
                 return 0 ;
             blockbuffer[0] += ycoef ;
             ycoef = blockbuffer[0] ;
             for(j = 0; j < 64 ; j ++)
                 *pMCUBuffer ++ = blockbuffer[j] ;
             for(i = 0; i < 128; i ++)
                 *pMCUBuffer ++ = 0 ;
             break ;
        default: 
              error("Error Jpg File format! default") ;
        } /* end switch */
        return (1) ;
    } /* end DecodeMCUBlock */


unsigned char readbyte(FILE *fp)
{
    unsigned char c ;
    c = fgetc(fp) ;
    if(c == 0xff)    /* 读入非0xff字节 */
        fgetc(fp) ;
    bitpos = 8 ;
    curbyte = c;
    return c ;
    } /* end readbyte */


int DecodeElement(FILE *fp)
{
    int codelength ;
    long thiscode, tempcode ;
    unsigned int temp, news ;
    unsigned char hufbyte, runsize, tempsize, sign ;
    unsigned char newbyte, lastbyte ;
    if(bitpos >= 1)
    {
        bitpos -- ;
        thiscode = (unsigned char) curbyte >> bitpos ;
        curbyte = curbyte & And[bitpos] ;
        } /* end if  */
    else
    {
        lastbyte = readbyte(fp) ;
        bitpos -- ;
        newbyte = curbyte & And[bitpos] ;
        thiscode = lastbyte >> 7 ;
        curbyte = newbyte ;
        } /* end else */
    codelength = 1 ;
    while((thiscode < hufmin[HufTabindex][codelength - 1])
        ||(codelen[HufTabindex][codelength - 1] == 0)
        ||(thiscode > hufmax[HufTabindex][codelength - 1]))
    {
        if(bitpos >= 1)
        {
            bitpos -- ;
            tempcode = (unsigned char) curbyte >> bitpos ;
            curbyte = curbyte & And[bitpos] ;
            } /* end if */
        else
        {
            lastbyte = readbyte(fp) ;
            bitpos -- ;
            newbyte = curbyte & And[bitpos] ;
            tempcode = (unsigned char) lastbyte >> 7 ;
            curbyte = newbyte ;
            } /* end else */
        thiscode = (thiscode << 1) + tempcode ;
        codelength ++ ;
        if(codelength > 16)
            error("Error Jpg File format! this") ;           
        } /* end while  */
    temp = thiscode - hufmin[HufTabindex][codelength - 1] + codepos[HufTabindex][codelength - 1] ;
    hufbyte = (unsigned char) codevalue[HufTabindex][temp] ;
    run = (int) (hufbyte >> 4) ;
    runsize = hufbyte & 0x0f ;
    if(runsize == 0)
    {
        value = 0 ;
        return 1 ;
        } /* end if */
    tempsize = runsize ;
    if(bitpos >= runsize)
    {
        bitpos -= runsize ;
        news = (unsigned char) curbyte >> bitpos ;
        curbyte = curbyte & And[bitpos] ;
        } /* end if */
    else
    {
        news = curbyte ;
        tempsize -= bitpos ;
        while(tempsize > 8)
        {
            lastbyte = readbyte(fp) ;
            news =(news << 8) + (unsigned char) lastbyte ;
            tempsize -= 8 ;
            } /* end while   */
        lastbyte = readbyte(fp) ;
        bitpos -= tempsize ;
        news = (news << tempsize) + (lastbyte >> bitpos) ;
        curbyte = lastbyte & And[bitpos] ;
        } /* end else  */
    sign = news >> (runsize - 1) ;
    if(sign)
        value = news ;
    else
    {
        news = news ^ 0xffff ;
        temp = 0xffff << runsize ;
        value = -(int) (news ^ temp) ;
        } /* end else  */
    return 1 ;
    } /* DecodeElement */  


 main( )
{
    FILE *fp1, *fp2 ;
    if((fp1 = fopen("Winter.jpg", "rb")) == NULL)
        error("Can not open Jpg File in main! ") ;
    if((fp2 = fopen("Winter.bmp", "wb")) == NULL)
        error("Can not create Bmp File in main!") ;
    initialize(fp1) ;
    makebmpheader(fp2) ;
    decode(fp1, fp2) ; 
    fclose(fp1) ;
    fclose(fp2) ;
} /* end main */