0
// Copies a BMP file

include

include

include "bmp.h"

int main(int argc, char *argv[]) { // ensure proper usage if (argc != 3) { printf("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)
{
    printf("Could not open %s.\n", infile);
    return 2;
}

// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
    fclose(inptr);
    printf("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);
    printf("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);
        // modify the pixels
        if ((triple.rgbtRed == 0xff && triple.rgbtGreen == 0x00 && 
         triple.rgbtBlue == 0x00) || (triple.rgbtRed == 0xff &&
         triple.rgbtGreen == 0xff && triple.rgbtBlue == 0xff))
        {
            triple.rgbtRed = 0x00;
            triple.rgbtGreen = 0x00;
            triple.rgbtBlue = 0x00;
        }
        // write RGB triple to outfile
        fwrite(&triple, 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;

}

0

Maybe those pixels you try to target are not exactly (255,0,0) and (255,255,255). Maybe some comparison operators like <, <=, >, >= would help, and maybe you don't need to check all the components. You seem to pick some of the pixels where the red component is 255, you could try to select those that have one component above or below some threshold. There are many ways to find readable output.

| improve this answer | |
  • Thank you very much I go it. But I could not get the purple quit right when I use 800080 it shows error. Thank you. – BMavhungu Nov 13 '19 at 10:11
  • Unconditionally assigning to the individual components should work for purple (the exact error message would help, but that sounds like another question). Similarly, unconditionally assigning to just some components (emulating the red filter which absorbs all the non-red light) would also work for whodunit. – Blauelf Nov 13 '19 at 12:28
  • Thank you I got and is working. – BMavhungu Nov 13 '19 at 13:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .