書き換えについて

解決


あらしじゃない  2006-05-01 23:27:17  No: 61577

// BMP2PDF (8bit/24bitのみ対応)

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>

typedef int                 BOOL;
typedef unsigned char       BYTE;
typedef unsigned short      WORD;
typedef unsigned long       DWORD;

#define FALSE               0
#define TRUE                1

BOOL  GetBMPSize(FILE *BMPStream,long *offset);
void  Write_CrossReferenceTable(FILE *AStream,DWORD ObjectPosArray[],int Count);
void  Write_ContentsObject(FILE *AStream,DWORD ObjectPosArray[],int *ObjectIndex,int w,int h);
int   BMPtoPDF(const char *OpenName,const char *SaveName);

int main(int argc,char *argv[])
{
   if (argc >= 2)
     return (BMPtoPDF(argv[1],"c:\\bmppdf.pdf"));
   else
   {
     printf("Not Found!\n");
     return(0);
   }   
}

/* 1ラインの幅を算出 */
int GetLineWidth(WORD biBitCount, int biWidth)
{
  return ((biBitCount * biWidth + 15) / 16) * 2 ;
}

/* イメージデータのサイズを算出 */
int GetBitsSize(int biWidth, int biHeight,WORD biBitCount)
{
    switch (biBitCount)
    {   
       case     1: return ( ((1 * biWidth + 15) / 16) * 2 * (biHeight) );break;
       case     4: return ( ((4 * biWidth + 15) / 16) * 2 * (biHeight) );break;
       case     8: return ( biWidth*biHeight )  ;break;
       case    24: return ( biWidth*biHeight*3 );break;
       default   : return ( 0 );break;
    }
}

/* イメージデータの取得 */
BOOL GetBitsData(FILE *AStream,int bfOffBits,BYTE *BitsData, int biWidth, int biHeight,WORD biBitCount)
{
 int i;
 BYTE Dummy[4],DummyCnt;

 fseek(AStream,bfOffBits,SEEK_SET);

 switch (biBitCount)
 {   
   case     1:;
   case     4:;
   case     8: 
                DummyCnt= biWidth % 4;
                switch (DummyCnt)
                {
                   case 0:
                       for (i=0;i< biHeight;i++)
                           fread(BitsData+(biWidth*i),1,biWidth,AStream); 
                       break;
                   case 1 :;
                   case 2 :;
                   case 3 :;
                       for (i=0;i< biHeight;i++)
                       {
                           fread(BitsData+(biWidth*i),1,biWidth,AStream); 
                           fread(Dummy,1,4-DummyCnt,AStream); 
                       }
                       break;
                   default: return (FALSE);                
                }
                break;
       
       ;break;
   case    24: 
                DummyCnt= biWidth % 4;
                switch (DummyCnt)
                {
                   case 0:
                       for (i=0;i< biHeight;i++)
                           fread(BitsData+(biWidth*3*i),1,biWidth*3,AStream); 
                       break;
                   case 1 :;
                   case 2 :;
                   case 3 :
                       for (i=0;i< biHeight;i++)
                       {
                           fread(BitsData+(biWidth*3*i),1,biWidth*3,AStream); 
                           fread(Dummy,1,DummyCnt,AStream); 
                       }
                       break;
                   default: return (FALSE);                
                }
                break;
 }
 return (TRUE);
}

/* イメージデータを反転させる */
BOOL TurnBits(BYTE *BitsData,int BitsSize,int biWidth,WORD biBitCount)
{
 int i,j,LineWidth=0;
 BYTE *buffer,*Linebuffer,tmp;

 // 1ラインの幅を算出
 switch (biBitCount)
 {   
   case     1: ;
   case     4: LineWidth=GetLineWidth(biBitCount,biWidth);break;
   case     8: LineWidth=biWidth;  break;
   case    24: LineWidth=biWidth*3;break;
 } 

 Linebuffer=(BYTE *)malloc(LineWidth);
 if (Linebuffer==NULL) 
   return FALSE;

 buffer=(BYTE *)malloc(BitsSize);
 if (buffer==NULL)
 {
   free(Linebuffer);
   return FALSE;
 }

 if (biBitCount==24)
 {
     for (i=0;i< (BitsSize / LineWidth);i++)
     {
         /* 1ラインを取得 */
        memcpy(Linebuffer,BitsData+(LineWidth*i),LineWidth); 
   
        /* BGR<->RGB変換 */  
        for (j=0;j<LineWidth ;j+=3)
        {
          tmp             = Linebuffer[j];
          Linebuffer[j]   = Linebuffer[j+2];
          Linebuffer[j+2] = tmp;
        }
        /* 1ラインをメモリに書き込む */
        memcpy(buffer+ (BitsSize- LineWidth * (i+1) ),Linebuffer,LineWidth);
     }
 }
 else
 {  
     for (i=0;i< (BitsSize / LineWidth);i++)
     {
        /* 1ラインを取得 */
        memcpy(Linebuffer,BitsData+(LineWidth*i),LineWidth); 
        /* 1ラインをメモリに書き込む */
        memcpy(buffer+ (BitsSize- LineWidth * (i+1) ),Linebuffer,LineWidth);
     }     
 }

 // 元のデータと置き換える
 memcpy(BitsData,buffer,BitsSize);

 free(buffer); free(Linebuffer);

 return(TRUE);
}

BOOL GetBMPSize(FILE *BMPStream,long *offset)
{
 //WORD wrk;
 //BYTE Sampling;

 //WORD SOF0 =0xFFC0; /* 通常 */
 //WORD SOF2 =0xFFC2; /* 進歩 */

/*----------------------------*/
/* ファイルヘッダ部 (14 Byte) */
/*----------------------------*/

  int count = 0;
  long var_long;
  short var_short;
  char s[10];

  // BITMAP 認識文字 "BM"
  if (fread(s, 2, 1, BMPStream) == 1) {
    if (memcmp(s, "BM", 2) == 0) {
      printf("[BM] BITMAP file\n");
    } 
    else {
      fprintf(stderr, "%s : Not a BITMAP file\n", s);
      exit(1);
    }
    count += 2;
  }
  printf("  [BITMAPFILEHEADER]\n");
  // ファイルサイズ
  if (fread(&var_long, 4, 1, BMPStream) == 1) {
    printf("  Size          : %ld [Byte]\n", var_long);
    count += 4;
  }
  // 予約領域 0
  if (fread(&var_short, 2, 1, BMPStream) == 1) {
    count += 2;
  }
  // 予約領域 0
  if (fread(&var_short, 2, 1, BMPStream) == 1) {
    count += 2;
  }
  // ファイルの先頭から画像データまでの位置
  if (fread(&var_long, 4, 1, BMPStream) == 1) {
    printf("  OffBits       : %ld [Byte]\n", var_long);
    *offset = var_long;
    count += 4;
  }
  return count;
}

/*------------------------------------------------------------------*/
/* 情報ヘッダ部 (12 Byte -> OS/2 Bitmap, 40 Byte -> Windows Bitmap) */
/*------------------------------------------------------------------*/
int infoheader(FILE *BMPStream,
               short *infosize,
               long *width, long *height,
               long *x_coodinate, long *y_coodinate,
               short *BitCount, 
               long *ClrUsed)
{
  int count = 0;
  long var_long, compress = 0;
  short var_short;

  // BITMAPINFOHEADER のサイズ
  if (fread(&var_long, 4, 1, BMPStream) == 1) {
    count += 4;
    *infosize = var_long;
  }

  printf("  [BITMAPINFOHEADER]\n");
  // OS/2 Bitmap
  if (*infosize == 12) {
    // 画像データの幅
    if (fread(&var_short, 2, 1, BMPStream) == 1) {
      printf("  Width         : %d [pixel]\n", var_short);
      *width = var_short;
      count += 2;
    }
    // 画像データの高さ 
    if (fread(&var_short, 2, 1, BMPStream) == 1) {
      printf("  Height        : %d [pixel]\n", var_short);
      *height = var_short;
      count += 2;
    }
    // プレーン数 (1のみ) 
    if (fread(&var_short, 2, 1, BMPStream) == 1) {
      count += 2;
    }
    // 1画素あたりのビット数 (1, 4, 8, 24, 32) 
    if (fread(&var_short, 2, 1, BMPStream) == 1) {
      printf("  BitCount      : %d [bit]\n", var_short);
      *BitCount = var_short;
      count += 2;
    }
  }
  // Windows BMP 
  else if (*infosize == 40) {
    // 画像データの幅 
    if (fread(&var_long, 4, 1, BMPStream) == 1) {
      printf("  Width         : %ld [pixel]\n", var_long);
      *width = var_long;
      count += 4;
    }
    // 画像データの高さ
    if (fread(&var_long, 4, 1, BMPStream) == 1) {
      printf("  Height        : %ld [pixel]\n", var_long);
      *height = var_long;
      count += 4;
    }
    // プレーン数 (1のみ) 
    if (fread(&var_short, 2, 1, BMPStream) == 1) {
      count += 2;
    }
    // 1画素あたりのビット数 (1, 4, 8, 24, 32) 
    if (fread(&var_short, 2, 1, BMPStream) == 1) {
      printf("  BitCount      : %d [bit]\n", var_short);
      *BitCount = var_short;
      count += 2;
    }
    // 圧縮方式  0 : 無圧縮 
    //           1 : BI_RLE8 8bit RunLength 圧縮 
    //           2 : BI_RLE4 4bit RunLength 圧縮 
    if (fread(&var_long, 4, 1, BMPStream) == 1) {
      printf("  Compression   : %ld\n", var_long);
      compress = var_long;
      count += 4;
    }
    // 画像データのサイズ 
    if (fread(&var_long, 4, 1, BMPStream) == 1) {
      printf("  SizeImage     : %ld [Byte]\n", var_long);
      count += 4;
    }
    // 横方向解像度 (Pixel/meter) 
    if (fread(&var_long, 4, 1, BMPStream) == 1) {
      printf("  XPelsPerMeter : %ld [pixel/m]\n", var_long);
      *x_coodinate = var_long;
      count += 4;
    }
    // 縦方向解像度 (Pixel/meter) 
    if (fread(&var_long, 4, 1, BMPStream) == 1) {
      printf("  YPelsPerMeter : %ld [pixel/m]\n", var_long);
      *y_coodinate = var_long;
      count += 4;
    }
    // 使用色数 
    if (fread(&var_long, 4, 1, BMPStream) == 1) {
      printf("  ClrUsed       : %ld [color]\n", var_long);
      *ClrUsed = var_long;
      count += 4;
    }
    // 重要な色の数 0の場合すべての色 
    if (fread(&var_long, 4, 1, BMPStream) == 1) {
      count += 4;
    }
  } 
  else {
    fprintf(stderr, "Bitmap Info Header error\n");
  }

  if (compress != 0) {
    fprintf(stderr, "圧縮ビットマップには対応していません\n");
    exit(1);
  }
  if (*BitCount == 4 || *BitCount == 8 || *BitCount == 24 || *BitCount == 32) {
    ;
  } 
  else {
    fprintf(stderr, "%d ビット色には対応していません\n", *BitCount);
    exit(1);
  }
  return count;
}

/*-------------*/
/* OS/2 bitmap */
/*-------------*/
int rgbtriple(FILE *BMPStream,
              long used,
              unsigned char *red,
              unsigned char *green, 
              unsigned char *blue)
{
  long i;
  int count = 0;

  // ビットの並びは B G R 
  for (i = 0; i < used; i++) {
    blue[i] = fgetc(BMPStream);
    green[i] = fgetc(BMPStream);
    red[i] = fgetc(BMPStream);
    count++;
  }

  return count;
}

/*----------------*/
/* Windows bitmap */
/*----------------*/
int rgbquad(FILE *BMPStream,
            long used,
            unsigned char *red, 
            unsigned char *green, 
            unsigned char *blue)
{
  long i;
  int receive, count = 0;

  // ビットの並びは B G R 予約 
  for (i = 0; i < used; i++) {
    blue[i] = fgetc(BMPStream);
    green[i] = fgetc(BMPStream);
    red[i] = fgetc(BMPStream);
    receive = fgetc(BMPStream);
    count++;
  }
  return count;
}

void Write_CrossReferenceTable(FILE *AStream,DWORD ObjectPosArray[],int Count)
{
   int i;

   fprintf(AStream,"xref\n");
   fprintf(AStream,"0 %d\n",Count+1);
   fprintf(AStream,"0000000000 65535 f \n");

   for (i= 0; i<=Count-1;i++)
      fprintf(AStream,"%0.10d 00000 n \n",ObjectPosArray[i]);
}

void Write_ContentsObject(FILE *AStream,DWORD ObjectPosArray[],int *ObjectIndex,int w,int h)
{
   int Length;

   /* PDFコンテンツ */
   ObjectPosArray[*ObjectIndex]  =(DWORD)ftell(AStream);
     fprintf(AStream,"%d 0 obj\n",*ObjectIndex+1);
     fprintf(AStream,"<< /Length %d 0 R >>\n",*ObjectIndex+2);
     fprintf(AStream,"stream\n");

        /* stream */
        Length=ftell(AStream);
          fprintf(AStream,"q\n");
          fprintf(AStream,"%d 0 0 %d 0 0 cm\n",w,h);
          fprintf(AStream,"/Im0 Do\n");
          fprintf(AStream,"Q\n");
        Length=ftell(AStream)-Length;

     fprintf(AStream,"endstream\n");
     fprintf(AStream,"endobj\n");
   *ObjectIndex=*ObjectIndex+1;

   /* stream Length */
   ObjectPosArray[*ObjectIndex] =(DWORD)ftell(AStream);
     fprintf(AStream,"%d 0 obj\n",*ObjectIndex+1);
     fprintf(AStream,"%d\n",Length);
     fprintf(AStream,"endobj\n");
   *ObjectIndex=*ObjectIndex+1;
}

int BMPtoPDF(const char *OpenName,const char *SaveName)
{
 int   ObjectIndex;
 short infosize, bits;
 long used = 0, color = 0, offset, width, height, xreso, yreso;
 unsigned char red[256],blue[256],green[256];
 DWORD ObjectPosArray[10];
 FILE  *BMPStream,*AStream;

 int i,j=0;
 DWORD BitsSize;          // イメージデータのサイズ
 BYTE *BitsData;          // イメージデータ
 BYTE  BitsPalette[768];  // カラーパレット 

    ObjectIndex=0;

    /* BMPファイルを開く*/
    BMPStream=fopen(OpenName,"rb");
    if(BMPStream==NULL)
    {
       printf("Error : Can not Open File.\n");
       return(-1);  
    }

   // ヘッダ情報 BITMAPFILEHEADER 
   GetBMPSize(BMPStream, &offset);
   // ヘッダ情報 BITMAPINFOHEADER 
   infoheader(BMPStream, &infosize, &width, &height, &xreso, &yreso, &bits, &color);
   //color = usedcolor(bits, color);

 // OS/2 Bitmap 
  if (infosize == 12) {
    if (bits == 1 || bits == 4 || bits == 8) {
      used = rgbtriple(BMPStream, color, red, green, blue);
    }
    printf("[OS/2 bitmap] --- %d bit %ld color\n", bits, used);
  }
  // Windows Bitmap 
  else if (infosize == 40) {
    if (bits == 1 || bits == 4 || bits == 8) {
      used = rgbquad(BMPStream, color, red, green, blue);
    }
    printf("[Windows bitmap] --- %d bit %ld color\n", bits, used);
  } 
  else if (infosize == 108) {
    printf("[other bitmap]\n");
  }
  else {
    fprintf(stderr, "BITMAP INFOHEADER error\n");
  }

    /* とりあえず、8bitと24bitのみ*/
    if (!(bits == 8 || bits == 24))
    {
       printf("Error : 対応していない形式です\n");
       fclose(BMPStream);
       return(-1);  
    }  
  
    /* PDFファイル作成 */
    AStream=fopen(SaveName,"wb+");
    if(AStream==NULL)
    {
        printf("Error : Can not Create File.\n");
        fclose(BMPStream);
        return(-1); 
    }

    /* ------------------------------------------------------------- */
    /*  Writting PDF (PDFの書式)                                     */
    /* ------------------------------------------------------------- */

    /* PDF のバージョン */
    fprintf(AStream,"%%PDF-1.2\n");

    /* Catalog */
    ObjectPosArray[ObjectIndex] =ftell(AStream);
      fprintf(AStream,"%d 0 obj\n",ObjectIndex+1);
      fprintf(AStream,"<<\n");
      fprintf(AStream,"/Type /Catalog\n");
      fprintf(AStream,"/Pages 2 0 R\n");
      /* View Option (100%) */
      fprintf(AStream,"/OpenAction [3 0 R /XYZ -32768 -32768 1 ]\n");
      fprintf(AStream,">>\n");
      fprintf(AStream,"endobj\n");
    ObjectIndex++;

     /* Parent Pages */
     ObjectPosArray[ObjectIndex] =ftell(AStream);
       fprintf(AStream,"%d 0 obj\n",ObjectIndex+1);
       fprintf(AStream,"<<\n");
       fprintf(AStream,"/Type /Pages\n");
       fprintf(AStream,"/Kids [ 3 0 R ]\n");
       fprintf(AStream,"/Count 1\n");
       fprintf(AStream,">>\n");
       fprintf(AStream,"endobj\n");
     ObjectIndex++;

     /* Kids Page */
     ObjectPosArray[ObjectIndex] =ftell(AStream);
       fprintf(AStream,"%d 0 obj\n",ObjectIndex+1);
       fprintf(AStream,"<<\n");
       fprintf(AStream,"/Type /Page\n");
       fprintf(AStream,"/Parent 2 0 R\n");
       fprintf(AStream,"/Resources\n");
       fprintf(AStream,"<<\n");
       fprintf(AStream,"/XObject << /Im0 4 0 R >>\n");

       // ProcSet
       switch (bits)
       {   
         case 4  :;
         case 8  : fprintf(AStream,"/ProcSet [ /PDF /ImageI ]\n");break;
         default : fprintf(AStream,"/ProcSet [ /PDF /ImageC ]\n");break;
       }       

       fprintf(AStream,">>\n");
       fprintf(AStream,"/MediaBox [ 0 0 %d %d ]\n",width,abs(height));

       // コンテンツのオブジェクト番号
       switch (bits)
       {   
         case 4  : ;
         case 8  : fprintf(AStream,"/Contents 6 0 R\n");break;
         default : fprintf(AStream,"/Contents 5 0 R\n");break;
       }           

       fprintf(AStream,">>\n");
       fprintf(AStream,"endobj\n");
     ObjectIndex++;

      /* XObject Resource */
      ObjectPosArray[ObjectIndex] =ftell(AStream); 
       fprintf(AStream,"%d 0 obj\n",ObjectIndex+1);
       fprintf(AStream,"<<\n");
       fprintf(AStream,"/Type /XObject\n");
       fprintf(AStream,"/Subtype /Image\n");
       fprintf(AStream,"/Name /Im0\n");
       fprintf(AStream,"/Width %d\n",width);
       fprintf(AStream,"/Height %d\n",abs(height));

       fprintf(AStream,"/Filter []\n");

       /* BitsPerComponent */
       switch (bits)
       {   
         case 1  : fprintf(AStream,"/BitsPerComponent 1\n");break; 
         case 4  : fprintf(AStream,"/BitsPerComponent 4\n");break;
         default : fprintf(AStream,"/BitsPerComponent 8\n");break;
       }                   

       /* ColorSpace */
       switch (bits)
       {   
          case     1   : fprintf(AStream,"/ColorSpace /DeviceGray\n");break; 
          case     4   : ;
          case     8   : fprintf(AStream,"/ColorSpace [/Indexed /DeviceRGB 255 %d 0 R]\n",ObjectIndex+2); break;
          case     24  : fprintf(AStream,"/ColorSpace /DeviceRGB\n");break;
       }
       
       /* イメージデータのサイズを算出 */
       BitsSize =GetBitsSize(width, abs(height),bits);
       fprintf(AStream,"/Length %d >>\n",BitsSize);

       /*  イメージデータの書き込み */       
       fprintf(AStream,"stream\n");
          
         /* 生データを突っ込む */     
         BitsData=(BYTE *)malloc(BitsSize);
          GetBitsData(BMPStream,offset,BitsData,width,height,bits);  
          TurnBits(BitsData,BitsSize,width,bits);
          fwrite(BitsData,1,BitsSize,AStream);
         free(BitsData);

       fprintf(AStream,"\nendstream\n");
       fprintf(AStream,"endobj\n");
     ObjectIndex++;

     // カラーパレットの書き込み
     if (bits==4 || bits==8)
     {
         for (i=0;i<768;i+=3)
         {
            BitsPalette[i]  = red[j];
            BitsPalette[i+1]= green[j];
            BitsPalette[i+2]= blue[j];
            j++;  
         }

        ObjectPosArray[ObjectIndex] =ftell(AStream); 
          fprintf(AStream,"%d 0 obj\n",ObjectIndex+1);
          fprintf(AStream,"<<\n");
          fprintf(AStream,"/Length 768\n");
          fprintf(AStream,"/Filter []\n");
          fprintf(AStream,">>\n");
          fprintf(AStream,"stream\n");
          fwrite(BitsPalette,1,768,AStream);
          fprintf(AStream,"\nendstream\n");
          fprintf(AStream,"endobj\n");
        ObjectIndex++;     
     }

    /* Contents Stream & Object */
    Write_ContentsObject(AStream,ObjectPosArray,&ObjectIndex,width,height);

    /* CrossReferenceTable */
    ObjectPosArray[ObjectIndex] =ftell(AStream);
    Write_CrossReferenceTable(AStream,ObjectPosArray,(int)ObjectIndex);

    /* trailer */
    fprintf(AStream,"trailer\n");
    fprintf(AStream,"<<\n");
    fprintf(AStream,"/Size %d\n",ObjectIndex+1);
    fprintf(AStream,"/Root 1 0 R\n");
    fprintf(AStream,">>\n");
    fprintf(AStream,"startxref\n");
    fprintf(AStream,"%d\n",ObjectPosArray[ObjectIndex]);
    fprintf(AStream,"%%%%EOF\n");

    fclose(BMPStream); fclose(AStream);

    printf("\nSuccess!\n");

    return (0);  
}

上記のプログラムを低水準ファイル入出力で書き換えたいのですがうまくいきません。
どうすれば良いでしょうか


επιστημη  2006-05-01 23:33:26  No: 61578

なにが/どう うまくいきません なのでしょうか?
これだけ長いコードを晒して"うまくいきません"の一言てのはないと思うぞ。


επιστημη  2006-05-01 23:39:19  No: 61579

ふ・ざ・け・ん・な


kure  2006-05-02 00:16:13  No: 61580

このコードって

http://madia.world.coocan.jp/vc/vc_bbs/200307_03070030.html

ここで出てるやつまんまかな??
だとしたら3年近く前の話!?

> 低水準ファイル入出力

って何を想定してるんだろ・・・。
fopenとか普通に使ってるみたいだし。
_openとかを想定してるのかな??


επιστημη  2006-05-02 03:14:47  No: 61581

…僕のハンドルを騙る阿呆がいるな。


じゃんぬねっと  URL  2006-05-02 18:55:11  No: 61582

デバッグというものはされているんでしょうか。
まず問題の切り分けありきだと思うのですが。

# 途中まで読んだけど工数が勿体無く断念。


あらしじゃない  2006-05-09 02:34:32  No: 61583

色々やってみてできました。

επιστημη様、じゃんぬねっと様ご迷惑をおかけしました。


どのように解決したか書きましょう  2006-05-09 03:02:43  No: 61584

> 色々やってみてできました。
その色々やったことを載せてください。
でないとカナリ失礼です。(これでおわったらあらしだろ)


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加