[C] Base64 encoding

Pagina: 1
Acties:

  • sariel
  • Registratie: Mei 2004
  • Laatst online: 07-12-2025
Ik ben bezig met een programmaatje dat een screenshot maakt, en deze base64 encode. Enige probleem is dat het base64 encoden niet helemaal werk: Na 257902 bytes stopt het inlezen van de 3mb grote bitmap, omdat om de een of andere reden eof gehaald is. kan een van jullie zien waarom dit zo is, en hoe het opgelost kan worden?
als ik een ander bestand encode kan het rustig honderden mb's aan zonder te stoppen....

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

/**************Base 64 encoding**********************/

/*
** Translation Table as described in RFC1113
*/
static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/*
** Translation Table to decode (created by author)
*/
static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";

/*
** encodeblock
**
** encode 3 8-bit binary bytes as 4 '6-bit' characters
*/
void encodeblock( unsigned char in[3], unsigned char out[4], int len )
{
    out[0] = cb64[ in[0] >> 2 ];
    out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
    out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
    out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
}

/*
** encode
**
** base64 encode a stream adding padding and line breaks as per spec.
*/
void encode( FILE *infile, FILE *outfile, int linesize )
{
    unsigned char in[3], out[4];
    int i, len = 0, blocksout = 0, read = 1, write = 1, r2 = 1;
    rewind(infile);

    while( !feof( infile )) {
        len = 0;
        for( i = 0; i < 3; i++ ) {
            in[i] = (unsigned char) getc( infile );

            r2++;
            if( !feof( infile )) {
                len++;
                read++;
            }
            else {
                in[i] = 0;
            }
        }
        if( len ) {
            encodeblock( in, out, len );
            for( i = 0; i < 4; i++ ) {
                putc( out[i], outfile );
                write ++;
            }
            blocksout++;
        }
        if( blocksout >= (linesize/4) || feof( infile ) ) {
            if( blocksout ) {
                fprintf( outfile, "\r\n" );
                write+=2;
            }
            blocksout = 0;
        }
    }
    printf("%d bytes read\n", read);
    printf("%d bytes written\n", write);
}

/**********End of base64 encoding************/

void  SaveCapturedBitmap(char *szFilename,HBITMAP hBitmap)
{
      HDC        hdc=NULL;
      FILE*      fp=NULL;
      LPVOID     pBuf=NULL;
      BITMAPINFO bmpInfo;
      BITMAPFILEHEADER  bmpFileHeader; 
      do {
            hdc=GetDC(NULL);
            ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
            bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
            GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); 
            if(bmpInfo.bmiHeader.biSizeImage<=0)
            bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
            if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL)
            {
                  //MessageBox( NULL, "Unable to Allocate Bitmap Memory", "Error", MB_OK|MB_ICONERROR);
                  break;
            }
            bmpInfo.bmiHeader.biCompression=BI_RGB;
            GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);       
            if((fp = fopen(szFilename,"wb"))==NULL)
            {
                  //MessageBox( NULL, "Unable to Create Bitmap File", "Error", MB_OK|MB_ICONERROR);
                  break;
            }
            bmpFileHeader.bfReserved1=0;
            bmpFileHeader.bfReserved2=0;
            bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
            bmpFileHeader.bfType='MB';
            bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); 
            fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
            fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
            fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); 
      } while(false);
      if(hdc)     ReleaseDC(NULL,hdc); 
      if(pBuf)    free(pBuf); 
      if(fp)      fclose(fp);

      fp = fopen(szFilename, "r");
      FILE* fp2 = fopen("encoded", "w");
      encode(fp, fp2, 2048);
      fclose(fp);
      fclose(fp2);
      fp = fopen("encoded", "r");
      fp2 = fopen("decoded.bmp", "w");
      decode(fp, fp2);
      fclose(fp);
      fclose(fp2);
}

void CaptureScreen()
{
    int     nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int     nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    HWND    hDesktopWnd = GetDesktopWindow();
    HDC     hDesktopDC = GetDC(hDesktopWnd);
    HDC     hCaptureDC = CreateCompatibleDC(hDesktopDC);
    HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight);

    SelectObject(hCaptureDC,hCaptureBitmap);
    BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,hDesktopDC,0,0,SRCCOPY);

    SaveCapturedBitmap("tempfile.bmp", hCaptureBitmap);                //Place holder - Put your code here to save the captured image to disk
    ReleaseDC(hDesktopWnd,hDesktopDC);
    DeleteDC(hCaptureDC);
    DeleteObject(hCaptureBitmap);
    return;
}

int main()
{
    CaptureScreen();
    return 0;
}

base64 code komt van base64.sf.net, dus zou theoretisch gezien goed moeten zijn. zou het kunnen zijn omdat ergens in de bitmap een EOF zit? Zou wel vreemd zijn, want dan zouden andere programmaatjes er ook problemen mee moeten hebben, toch?

Copy.com


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je leest/schrijft je files als text ipv als binary. Zie de documentatie van fopen().

[ Voor 24% gewijzigd door .oisyn op 21-09-2006 16:19 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • sariel
  • Registratie: Mei 2004
  • Laatst online: 07-12-2025
argh.....inderdaad....wordt nu netjes encoded, op de volle lengte. alleen decoden gaat nog niet super, maar dat is voor later een probleem :)

Bedankt .oisyn.

* sariel heeft te lang zitten kijken naar encoding om fopen te zien....

[ Voor 18% gewijzigd door sariel op 21-09-2006 16:22 ]

Copy.com