2017-07-19 99 views
3
/** 
* Copies a BMP piece by piece, just because. 
* All we have to do is change all the red pixels to 


*/ 

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

#include "bmp.h" 

int main(int argc, char *argv[]) 
{ 
    // ensure proper usage 
    if (argc != 3) 
    { 
     fprintf(stderr, "Usage: ./copy infile outfile\n"); 
     return 1; 
    } 

    // remember filenames 
    char *infile = argv[1]; 
    char *outfile = argv[2]; 

    // open input file 
    FILE *inptr = fopen(infile, "r"); 
    if (inptr == NULL) 
    { 
     fprintf(stderr, "Could not open %s.\n", infile); 
     return 2; 
    } 

    // open output file 
    FILE *outptr = fopen(outfile, "w"); 
    if (outptr == NULL) 
    { 
     fclose(inptr); 
     fprintf(stderr, "Could not create %s.\n", outfile); 
     return 3; 
    } 

    // read infile's BITMAPFILEHEADER 
    BITMAPFILEHEADER bf; 
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr); 

    // read infile's BITMAPINFOHEADER 
    BITMAPINFOHEADER bi; 
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr); 

    // ensure infile is (likely) a 24-bit uncompressed BMP 4.0 
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
     bi.biBitCount != 24 || bi.biCompression != 0) 
    { 
     fclose(outptr); 
     fclose(inptr); 
     fprintf(stderr, "Unsupported file format.\n"); 
     return 4; 
    } 

    // write outfile's BITMAPFILEHEADER 
    fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr); 

    // write outfile's BITMAPINFOHEADER 
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr); 

    // determine padding for scanlines 
    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; 

    // iterate over infile's scanlines 
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++) 
    { 
     // iterate over pixels in scanline 
     for (int j = 0; j < bi.biWidth; j++) 
     { 
      // temporary storage 
      RGBTRIPLE triple; 

      // read RGB triple from infile 
      fread(&triple, sizeof(RGBTRIPLE), 1, inptr); 

      RGBTRIPLE red = {0, 0, 255}; 
      int same = 0; 
      RGBTRIPLE white = {255, 255, 255}; 

      if(&red.rgbtRed == &triple.rgbtRed && &red.rgbtGreen != &triple.rgbtRed && &red.rgbtBlue != &triple.rgbtRed) 
      { 
       same = 1; 
      } 

      if(same == 0) //copy the pixel, if the pixel isn't red 
      { 
       // write RGB triple to outfile 
       fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);  
      } 
      if(same == 1) 
      { 
       fwrite(&white, sizeof(RGBTRIPLE), 1, outptr); 
      } 

     } 

     // skip over padding, if any 
     fseek(inptr, padding, SEEK_CUR); 

     // then add it back (to demonstrate how) 
     for (int k = 0; k < padding; k++) 
     { 
      fputc(0x00, outptr); 
     } 
    } 

    // close infile 
    fclose(inptr); 

    // close outfile 
    fclose(outptr); 

    // success 
    return 0; 
} 

我的问题是更具体的代码的这一段:调试器跳过整个if语句

// temporary storage 
      RGBTRIPLE triple; 

      // read RGB triple from infile 
      fread(&triple, sizeof(RGBTRIPLE), 1, inptr); 

      RGBTRIPLE red = {0, 0, 255}; 
      int same = 0; 
      RGBTRIPLE white = {255, 255, 255}; 

      if(&red.rgbtRed == &triple.rgbtRed && &red.rgbtGreen != &triple.rgbtRed && &red.rgbtBlue != &triple.rgbtRed) 
      { 
       same = 1; 
      } 

      if(same == 0) //copy the pixel, if the pixel isn't red 
      { 
       // write RGB triple to outfile 
       fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);  
      } 
      if(same == 1) 
      { 
       fwrite(&white, sizeof(RGBTRIPLE), 1, outptr); 
      } 

我想在一个bmp文件到另一个文件复制,但摆脱任何红色,并用白色代替(这些代码大部分不是我的工作,它的预先编写的代码,我应该为作业编辑),复制功能可以工作,但由于某种原因检测到红色并将其替换为白色不管用。奇怪的是,当我使用调试器,它完全跳过的这部分代码:

if(&red.rgbtRed == &triple.rgbtRed && &red.rgbtGreen != &triple.rgbtRed && &red.rgbtBlue != &triple.rgbtRed) 
     { 
      same = 1; 
     } 

这是我在哪里检测如果该像素是红色,调试器充当如果该行不存在。

+3

'&stuff.other'将返回一个地址,而不是实际值。那是你要的吗?如果我是编译器,那么我会优化这条线,因为表达式总是错误的。 – ForceBru

+1

您正在比较地址而不是内容。摆脱&。 –

回答

3

不要拿地址,你不需要在所有使用int same变量。

if(red.rgbtRed == triple.rgbtRed && red.rgbtGreen != triple.rgbtRed && red.rgbtBlue != triple.rgbtRed) 
{ 
    fwrite(&white, sizeof(RGBTRIPLE), 1, outptr); 
} 
else 
{ 
    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr); 
} 
2

不要比较地址,它总是会失败。比较值,在简单的整数比较结果

if(red.rgbtRed == triple.rgbtRed && red.rgbtGreen != triple.rgbtRed && red.rgbtBlue != triple.rgbtRed) { 
    same = 1; 
} 
+1

就是这样!对于地址和指针还是一个新东西,所以我还没有完全掌握它。谢谢! –

2

您的编译器可能会检测到此“if”条件始终为false,并会优化这些行。因此,这部分代码不存在于您的可执行文件中,您的调试程序看不到它。

+0

好的!不知道编译器是这么做的。谢谢。 –