2012-04-09 69 views
0

我有一個C數組,看起來像這樣:如何從C-hexvalues生成文件?

char hexc[] = { 
    0x41, 0x80, 0x7a, 0x39, 0xea, 0x7e, 0x27, 0xfc, 
    0xe6, 0x45, 0x9c, 0x8b, 0xb5, 0xce, 0xa7, 0x35, 
    0x5f, 0xf2, 0x43, 0xcf, 0x89, 0xd8, 0x61, 0xec, 
    0xe7, 0xed, 0x2e, 0x34, 0x45, 0x0c, 0x32, 0xae, 
    0x71, 0x4f, 0x1c, 0xd8, 0xb5, 0x8c, 0x1e, 0xdd, 
    0x5d, 0x90, 0xf3, 0xf2, 0xe7, 0xa6, 0x4f, 0xef, 
    0xec, 0x96, 0xe3, 0xca, 0x8e, 0xeb, 0x64, 0x1d, 
    0x18, 0xa9, 0x95, 0xec, 0x64, 0x02, 0xf8, 0x26, 
}; 

我知道這背後的十六進制表示是一個.gif文件,什麼是從這個十六進制值產生一個可見的文件的最好方法再次?以及如何添加缺少的GIF頭?

+1

[你嘗試過什麼(HTTP:// mattgemmell .COM/2008/12/08 /什麼具備的,你試了/)?見['fopen()'](http://linux.die.net/man/3/fopen)和['fwrite()'](http://linux.die.net/man/3/fwrite) 。 – maerics 2012-04-09 14:59:46

+0

小端。我寧願C :)。 – 2012-04-09 15:02:28

+1

@Cameron:endinaness在char值上不應該有問題 – 2012-04-09 15:02:53

回答

3

你只打開文件,並寫入到它:

FILE *f = fopen("filename.gif", "wb"); 
if (!f) return; // or do something else 
fwrite(hexc, 1, sizeof(hexc), f); 
fclose(f); 

確保#include <stdio.h>

+0

不好,你需要以某種方式添加一個有效的GIF頭,因爲那個數據沒有。 – 2012-04-09 15:05:40

+0

@Ben Voigt OP沒有明確表示數據不包含GIF頭,只是它是一個GIF文件。 – 2012-04-09 15:06:25

+0

不應該以二進制模式打開文件嗎? – keety 2012-04-09 15:07:07

0

打開該文件作爲二進制

ofstream outfile ("new.gif",ofstream::binary); 

,然後寫你的緩衝

outfile.write (hexc, sizeof hexc); 
+0

您在C問題中使用C++函數和符號。 – 2012-04-09 15:18:52

+0

的確,但我的帖子後刪除了C++標籤。 – Marius 2012-04-10 09:23:09

+0

夠公平的。我沒有注意到。 – 2012-04-10 15:03:58

0

Turbo C的DOS代碼

/**************************************************************************** 
** This support Compuserve 256 colour GIF87a and GIF89a image up to  ** 
** 320x200 in size.              ** 
****************************************************************************/ 

//This program requires a stack of at least 19.5K!! 

#include "stdio.h" 

typedef 
    struct GIFHeader { 
    char   Signature [7]; 
    unsigned int ScreenWidth, ScreenHeight; 
    unsigned char Depth, Background, Zero; 
    }; 
    struct GIFDescriptor { 
    char   Separator; 
    unsigned int ImageLeft, ImageTop, ImageWidth, ImageHeight; 
    unsigned char Depth; 
    }; 

    char far *Screen = (char far *)0xA0000000L; 
    //For loading from the file 
    FILE     *GIFFile; 
    unsigned int   BPointer; 
    unsigned char  Buffer [257]; 
    //GIF data is stored in blocks of a certain size 
    unsigned char  BlockSize; 
    //For loading the code 
    unsigned char  CodeSize; 
    char     BitsIn; 
    unsigned char  Temp; 
    //Coordinates 
    unsigned int   X, Y, tlX, tlY, brX, brY; 
    //The string table 
    unsigned int   Prefix [4096]; 
    unsigned char  Suffix [4096]; 

//This sets the display to VGA 320x200 in 256 colours 
void VGAScreen() 
{ 
    asm { 
    mov ax, 0x13 
    int 0x10 
    } 
} 

//This resets the display to text mode 
void TextScreen() 
{ 
    asm { 
    mov ax, 0x3 
    int 0x10 
    } 
} 

//This sets a DAC register to a specific Red Green Blue-value 
void SetDAC(unsigned char DAC, unsigned char R, unsigned char G, unsigned char B) 
{ 
    outportb (0x3C8, DAC); 
    outportb (0x3C9, R); 
    outportb (0x3C9, G); 
    outportb (0x3C9, B); 
} 

//This sets one pixel on the screen 
void PutPixel (unsigned int x, unsigned int y, unsigned char c) 
{ 
    Screen [(y << 8) + (y << 6) + x] = c; 
} 

//Function to read from the buffer 
unsigned char LoadByte() 
{ 
    //Read next block} 
    if (BPointer == BlockSize) { 
    fread (Buffer, BlockSize + 1, 1, GIFFile); 
    BPointer = 0; 
    } 

    //Return byte 
    return Buffer [BPointer++]; 
} 

//Procedure to read the next code from the file 
unsigned int ReadCode() 
{ 
    int   Counter; 
    unsigned int Code; 

    Code = 0; 
    //Read the code, bit by bit 
    for (Counter = 0; Counter < CodeSize; Counter++) { 
    //Maybe, a new byte needs to be loaded with a further 8 bits 
    if (++BitsIn == 9) { 
     Temp = LoadByte(); 
     BitsIn = 1; 
    } 

    //Add the current bit to the code 
    if (Temp & 1) Code += 1 << Counter; 
    Temp >>= 1; 
    } 
    return Code; 
} 

//Procedure to draw a pixel 
void NextPixel (unsigned int c) 
{ 
    //Actually draw the pixel on screen 
    PutPixel (X, Y, c & 255); 

    //Move to next row, if necessary 
    if (++X == brX) { 
    X = tlX; 
    Y++; 
    } 
} 

//Local function to output a string. Returns the first character. 
unsigned char OutString (unsigned int CurCode) 
{ 
    unsigned int OutCount; 
    unsigned char OutCode [1024]; 

    //If it's a single character, output that 
    if (CurCode < 256) { 
    NextPixel (CurCode); 
    } else { 
    OutCount = 0; 

    //Store the string, which ends up in reverse order 
    do { 
     OutCode [OutCount++] = Suffix [CurCode]; 
     CurCode = Prefix [CurCode]; 
    } while (CurCode > 255); 

    //Add the last character 
    OutCode [OutCount++] = CurCode; 

    //Output all the string, in the correct order 
    do { 
     NextPixel (OutCode [--OutCount]); 
    } while (OutCount); 
    } 
    //Return 1st character 
    return CurCode; 
} 

//This actually loads the GIF 
void LoadGIF (char *Filename) 
{ 
    //For loading from the GIF file 
    struct GIFHeader  Header; 
    struct GIFDescriptor Descriptor; 

    //Colour information 
    unsigned char  BitsPerPixel, 
         NumOfColours; 
    unsigned int   DAC; 
    unsigned char  Palette [256][3]; 

    //For indexing the string table 
    unsigned int   FirstFree, FreeCode; 

    //All the code information 
    unsigned char  InitCodeSize; 
    unsigned int   Code, OldCode, MaxCode; 

    //Special codes 
    unsigned int   ClearCode, EOICode; 

    //Check whether the GIF file exists, and open it 
    GIFFile = fopen (Filename, "rb"); 
    if (GIFFile == 0) { 
    TextScreen(); 
    printf ("Could not open file %s", Filename); 
    return; 
    } 

    //Read header 
    fread (&Header, 6, 1, GIFFile); 
    Header.Signature [6] = 0; 
    fread (&Header.ScreenWidth, sizeof (Header) - 7, 1, GIFFile); 

    //Check signature and terminator 
    if ((strcmp (Header.Signature, "GIF87a") 
    && strcmp (Header.Signature, "GIF89a")) 
    || Header.Zero) { 
    TextScreen(); 
    printf ("Not a valid GIF file\n"); 
    return; 
    } 

    //Get amount of colours in image 
    BitsPerPixel = 1 + (Header.Depth & 7); 
    NumOfColours = (1 << BitsPerPixel) - 1; 

    //Load global colour map 
    fread (Palette, 3, (NumOfColours + 1), GIFFile); 
    for (DAC = 0; DAC <= NumOfColours; DAC++) 
    SetDAC (DAC, Palette [DAC][0] >> 2, 
       Palette [DAC][1] >> 2, 
       Palette [DAC][2] >> 2); 

    //Load the image descriptor 
    fread (&Descriptor, sizeof (Descriptor), 1, GIFFile); 

    if (Descriptor.Separator != ',') { 
    TextScreen(); 
    printf ("Incorrect image descriptor.\n"); 
    return; 
    } 

    //Get image corner coordinates 
    tlX = Descriptor.ImageLeft; 
    tlY = Descriptor.ImageTop; 
    brX = tlX + Descriptor.ImageWidth; 
    brY = tlY + Descriptor.ImageHeight; 

    //Some restrictions apply 
    if (Descriptor.Depth & 128) { 
    TextScreen(); 
    printf ("Local colour maps not supported\n"); 
    return; 
    } 
    if (Descriptor.Depth & 64) { 
    TextScreen(); 
    printf ("Interlaced images not supported\n"); 
    return; 
    } 

    //Get initial code size 
    fread (&CodeSize, 1, 1, GIFFile); 

    //GIF data is stored in blocks, so it's necessary to know the size 
    fread (&BlockSize, 1, 1, GIFFile); 

    //Start loader 
    BPointer = BlockSize; 

    //Special codes used in the GIF spec 
    ClearCode  = 1 << CodeSize;  //Code to reset 
    EOICode   = ClearCode + 1;  //End of file 

    //Initialize the string table 
    FirstFree  = ClearCode + 2;  //Strings start here 
    FreeCode   = FirstFree;   //Strings can be added here 

    //Initial size of the code and its maximum value 
    InitCodeSize  = ++CodeSize; 
    MaxCode   = 1 << CodeSize; 

    BitsIn = 8; 

    //Start at top left of image 
    X = Descriptor.ImageLeft; 
    Y = Descriptor.ImageTop; 

    do { 
    //Read next code 
    Code = ReadCode(); 

    //If it's an End-Of-Information code, stop processing 
     if (Code == EOICode) break; 
    //If it's a clear code... 
    else if (Code == ClearCode) { 
     //Clear the string table 
     FreeCode = FirstFree; 

     //Set the code size to initial values 
     CodeSize = InitCodeSize; 
     MaxCode = 1 << CodeSize; 

     //The next code may be read 
     Code = ReadCode(); 
     OldCode = Code; 

     //Set pixel 
     NextPixel (Code); 
    //Other codes 
    } else { 
     /*If the code is already in the string table, it's string is displayed, 
     and the old string followed by the new string's first character is 
     added to the string table.*/ 
     if (Code < FreeCode) 
     Suffix [FreeCode] = OutString (Code); 
     else { 
     /*If it is not already in the string table, the old string followed by 
     the old string's first character is added to the string table and 
     displayed.*/ 
     Suffix [FreeCode] = OutString (OldCode); 
     NextPixel (Suffix [FreeCode]); 
     } 

     //Finish adding to string table 
     Prefix [FreeCode++] = OldCode; 

     //If the code size needs to be adjusted, do so 
     if (FreeCode >= MaxCode && CodeSize < 12) { 
     CodeSize++; 
     MaxCode <<= 1; 
     } 

     //The current code is now old 
     OldCode = Code; 
    } 
    } while (Code != EOICode); 

    //Close the GIF file 
    fclose (GIFFile); 
} 

void main (int argcount, char *argvalue[]) 
{ 
    char FileName [80]; 

    //Check if a filename was passed as a parameter, otherwise ask for one 
    if (argcount > 1) { 
    strcpy (FileName, argvalue [1]); 
    } else { 
    printf ("Enter filename:"); 
    gets (FileName); 
    } 

    //Switch to graphics screen 
    VGAScreen(); 
    //Load GIF file 
    LoadGIF (FileName); 
    //Wait for keypress 
    getch(); 
    //Switch back to text mode 
    TextScreen(); 
} 
+1

這是讀取GIF文件的代碼... – 2012-04-09 15:13:40

+0

我同意這讀取文件,但它確實包含一些關於GIF文件結構的信息(可能適用於生成GIF文件)。 – 2012-04-09 15:21:37