是否有更好的方法来处理位图数据取决于压缩+ bitcount?

时间:2017-04-29 18:19:52

标签: c++ performance bitmap bmp bitmask

我一直在研究Bitmap(.bmp)文件格式一段时间,试图找出如何构建read函数。一般的想法是支持所有常见的压缩类型,安全并且仍然可以快速加载到(自定义)通用内存映像中,以便在机器视觉库中进行进一步处理。

考虑到性能,我认为最好为每个bitcount +压缩类型星座编写一个尽可能高效的循环。以下是BI_RGB的搜索结果:

if (bmpi.biCompression == BI_RGB){
    if (bmpi.biBitCount >= 24){
        // Here, every byte is each channel's value (assuming order is GBR(A))
        for (y = start_y; y != end_y; y += direction){
            row = y * stride;
            for (x = 0; x < stride; x += bpp){
                index = row + x;
                *(res->data++) = read_data[index + 2]; // R
                *(res->data++) = read_data[index + 1]; // G
                *(res->data++) = read_data[index];     // B
            }
        }
    }
    else if (bmpi.biBitCount == 16){
        // Without a bitfield mask, it's assumed 555 (instead of the common 565) with the last bit discarded
        for (y = start_y; y != end_y; y += direction){
            row = y * stride;
            for (x = 0; x < stride; x += bpp){
                val = (WORD)&read_data[row + x];
                *(res->data++) = map16to255[((val >> 10) & 31)]; // R
                *(res->data++) = map16to255[((val >> 5) & 31)];  // G
                *(res->data++) = map16to255[(val & 31)];         // B
            }
        }
    }
    else if (bmpi.biBitCount == 8){
        for (y = start_y; y != end_y; y += direction){
            row = y * stride;
            for (x = 0; x < stride; x += bpp){
                memcpy(res->data, &colors[read_data[row + x]], 3); // Copy RGB from color table
                res->data += 3; // Increment
            }
        }
    }
    else if (bmpi.biBitCount == 4){
        // 2 pixels per byte
        for (y = start_y; y != end_y; y += direction){
            row = y * stride;
            for (x = 0; x < stride; x += bpp){
                index = row + x;
                memcpy(res->data, &colors[(read_data[index] & 15)], 3);
                res->data += 3;
                memcpy(res->data, &colors[(read_data[index] >> 4)], 3);
                res->data += 3;
            }
        }
    }
    else{
        // 8 pixels per byte
        for (y = start_y; y != end_y; y += direction){
            row = y * stride;
            for (x = 0; x < stride; x += bpp){
                index = row + x;
                for (i = 0; i < 8; i++){
                    memcpy(res->data, &colors[((read_data[index] >> i) & 1)], 3);
                    res->data += 3;
                }
            }
        }
    }
}

说实话,它看起来不漂亮。 然后我考虑分配一个函数指针,只写一个循环,但担心它会以某种方式使它变慢。至少它会添加一层混淆(正在发生的事情)。如果它清楚地显示正在发生的事情以及目的是什么,我宁愿拥有臃肿的代码

typedef void(*pxl_proc) (int index, BYTEP read_data, BYTEP in_data, PRGBQUAD colors);    
//...
pxl_proc func = _24_rgb;
for (y = start_y; y != end_y; y += direction){
    row = y * stride;
    for (x = 0; x < stride; x += bpp){
        func(row + x, read_data, res->data, colors);
    }
}

我感觉这种方法是不必要的,并且有一种处理位图的一般方法,同时仍然快速或快速。

我该怎么做?这个&#34;足够好&#34;专业图书馆?

0 个答案:

没有答案