1
\$\begingroup\$

Reffering other "Stack Exchange" Sources, I've been told that the only way of swapping BGR to RGB involves buffering. While this isn't true, I could just perofrm a quick C-SA algorithm on fseek or bmp buffer byte offsets. I wrote a fast implementation of fwrite, that swaps the first byte with the 3rd. I do believe that this operation is not slower then the regular one.

size_t fwrite_ps ( const void * ptr, size_t size, size_t count, FILE * stream )
{
    size_t i, chr = 0;
    char p;
    signed pc = 0;

    for(i = 0; i != count * size; i++)
    {
        switch(pc)
        {
            case 1  :   p = 0;          break;
            case 2  :   p = (-2);       break;
            default :   p = 2; pc = 0;  break;
        }

        if( fputc( ((unsigned char*)ptr)[(i+p) - 0], stream ) != EOF ) { chr++; pc++; }
        else                                                           { break; }
    }
    return chr / size;
}

I like my style of codding. For me, it is pretty readable even after years. If it is not as readable for others, it might be because they are most likely used to other, more common styles.

I would like to enhance the utility of this, so i will also provide a really fast way of copying pixels in the proper order. Except functional and fast, it also simplifies varieties of different standarts. It will not copy padding and it involves only one loop.

#define IMAGE_NAME "sample.bmp"

typedef unsigned short WORD;
typedef unsigned long DWORD;

DWORD WIDTH     = BMPDATA[18] + BMPDATA[19] * 256; // Max width 65791
DWORD HEIGHT    = BMPDATA[22] + BMPDATA[23] * 256; // Max height 65791
DWORD h;
FILE* fp = fopen(IMAGE_NAME, "rb");

fprintf(fp, "P6\n%i %i\n%i\n", WIDTH, HEIGHT, 255);  // Copies PPM data

for(h = (HEIGHT-1)*((WIDTH*3) + WIDTH%4); h>=0; h -= (WIDTH*3) + (WIDTH%4))
{
    fwrite_ps(&BMPDATA[BMPDATA[10] + h], 1, WIDTH*3, fp);
}
// BMPDATA is your buffer containing a bmp image.
\$\endgroup\$
2
\$\begingroup\$

In fwrite_ps, the purpose of the switch seem to be to rotate the values of p as 2 -> 0 -> -2. Unless I'm overlooking something, it seems to me you could use i and some modulo and arithmetics for the same effect, like this:

for(i = 0; i != count * size; i++)
{
    // i = 0 => -2 * -1 = 2
    // i = 1 => -2 *  0 = 0
    // i = 2 => -2 *  1 = -2
    p = -2 * (i % 3 - 1);

    if( fputc( ((unsigned char*)ptr)[(i+p) - 0], stream ) != EOF ) { chr++; }
    else                                                           { break; }
}

About using all-cap names not for macros...

The reason why all-caps is not so good for pretty much anything is that it's typically used for macros. One day you might include a header file that defines a macro that conflicts with a variable name you defined and your build will fail spectacularly with bizarre errors.

\$\endgroup\$
1
  • \$\begingroup\$ This IS part of a libary. But anyway.. I haven't been thinking of other ways of implying circuit-swap algorithm. That obviouslly works. Wonderful. \$\endgroup\$ – Edenia Nov 9 '14 at 2:41
3
\$\begingroup\$
  • Magic numbers

    What is the significance of 18, 19, 22 and 23? They must be defined in terms of bitmap file header and bitmap info header

  • Correctness

    • According to a spec, bitmap width and bitmap height are 4 byte integers. The code accounts only for 2 bytes.

    • The code completely ignores colour depth.

    • The code is unable to deal with palette-based bitmaps.

    • The code completely ignores possible DIB compression.

  • Style

    • All-uppercase words are usually reserved for macros. Normal variable's identifiers should be in snake_case or camelCase.

    • What is the purpose of typedefing DWORD?

    • You should at least make your snippet into a function. Otherwise it is completely useless.

\$\endgroup\$
3
  • \$\begingroup\$ 18, 19, 22, 23 are offsets importantless. Have you seen such extremely large bitmaps with the size of 6k pixels per Width/Height? I haven't. This is just additional operation for the processor to proceed. 99% THAT is what i call pointless. \$\endgroup\$ – Edenia Nov 8 '14 at 20:42
  • \$\begingroup\$ The code is meant for the color deapth. 24 bpp, 8bpb cp.. what you mean by palette-based bitmaps? That makes no sense. Haha it is certainly not meant for compressed bitmaps. Noone compress them in buffer?? \$\endgroup\$ – Edenia Nov 8 '14 at 20:43
  • \$\begingroup\$ This is also not true. DWORD, WORD and BYTE are windows-specific datatype identifiers. And what, you can't copy-pase this in main instead of everywhere else? \$\endgroup\$ – Edenia Nov 8 '14 at 20:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.