0

私は次のようなC配列を持っています:

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, 
};

この16進表現の背後に.GIFファイルがあることを私は知っていましたが、この16進値から表示可能なファイルを再度生成するための最良の方法は何ですか?そして、不足しているGIFヘッダーを追加する方法は?

4

3 に答える 3

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>

于 2012-04-09T15:04:41.883 に答える
0

TurboCDOSコード

/****************************************************************************
** 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 ();
}
于 2012-04-09T15:11:47.937 に答える
0

ファイルをバイナリとして開く

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

その後、バッファを書き込みます

outfile.write (hexc, sizeof hexc);
于 2012-04-09T15:08:45.283 に答える