C 水平翻转1bpp.bmp图像

C 水平翻转1bpp.bmp图像,c,assembly,image-processing,x86,C,Assembly,Image Processing,X86,我正在尝试编写一个包含两个源文件的程序:用C编写的主程序和可从C调用的汇编(x86 32和64)模块。汇编例程的C声明如下所示: 空心镜BMP1(空心*img,内部宽度,内部高度) 这项任务包括水平镜像/翻转1 bpp.BMP图像,同时正确处理任何图像宽度,而不仅仅是8的倍数 我对汇编编程还不熟悉,对于如何完成这个任务几乎一无所知 任何帮助都将不胜感激。解决方案应基于汇编程序中的移位和旋转指令。如果您知道如何使用宏编程,您可以制作一个智能宏,它将为每个图像宽度(最后一个字节中的0到7位)生成8个

我正在尝试编写一个包含两个源文件的程序:用C编写的主程序和可从C调用的汇编(x86 32和64)模块。汇编例程的C声明如下所示: 空心镜BMP1(空心*img,内部宽度,内部高度)

这项任务包括水平镜像/翻转1 bpp.BMP图像,同时正确处理任何图像宽度,而不仅仅是8的倍数

我对汇编编程还不熟悉,对于如何完成这个任务几乎一无所知


任何帮助都将不胜感激。

解决方案应基于汇编程序中的移位和旋转指令。如果您知道如何使用宏编程,您可以制作一个智能宏,它将为每个图像宽度(最后一个字节中的0到7位)生成8个版本的例程

宽度为8的倍数的基本情况示例:

;al ... byte from input
;bl ... for output

;load from [esi] to al and move to next byte:
lodsb

repeat 8x:
shr al
rol bl

;store bl do [edi] and move to previous byte:
mov [edi],bl
dec edi
repeat 3x:
shr al
rol bl

lodsb

repeat 5x:
shr al
rol bl

mov [edi],bl
dec edi
宽度不是8的倍数的示例:

;al ... byte from input
;bl ... for output

;load from [esi] to al and move to next byte:
lodsb

repeat 8x:
shr al
rol bl

;store bl do [edi] and move to previous byte:
mov [edi],bl
dec edi
repeat 3x:
shr al
rol bl

lodsb

repeat 5x:
shr al
rol bl

mov [edi],bl
dec edi

我希望这些简短的例子能给你足够的指导,这样你就可以自己制定完整的解决方案。祝你好运。

如果图像是.BMP,那么每一行都对齐在DWORD边界上,因此至少每一行的开头对齐在字节边界上

要镜像映像,必须反转每个字节中的位顺序,还必须反转字节顺序。它们可以很容易地结合在一起:

void rev_line(unsigned char* line, unsigned char* tmp_buff, int line_sz){
    unsigned char* line2 = line + line_sz/8 - 1; // last complete byte of the input buffer
    int bit_delta = line_sz % 8; // number of unaligned bits. 
    // special case for bit_delta == 0 :
    if (!bit_delta){ // just reverse the input
        while (line < line2){
            unsigned char c = reverse(*line);
            *line++ = reverse(*line2);
            *line2-- = c;
        };
        if (line == line2) // odd number of bytes, so we'll just reverse it.
            *line = reverse(*line);
        return;
    };
    // now we have to take bit_delta bits from 
    for (; line2 >= line; line2--)
        *tmp_buff++ = (reverse(line2[1]) >> (8 - bit_delta) | // not sure about endianness here!
                      (reverse(line2[0]) << bit_delta;
    memcpy(line, tmp_buff, (line_sz + 7) / 8);
};
void rev_行(无符号字符*行,无符号字符*tmp_buff,int行_sz){
unsigned char*line2=line+line_sz/8-1;//输入缓冲区的最后一个完整字节
int bit_delta=line_sz%8;//未对齐的位数。
//位_delta==0的特殊情况:
如果(!bit_delta){//只需反转输入即可
while(第行<第2行){
无符号字符c=反向(*行);
*行++=反向(*行2);
*第2行--=c;
};
如果(line==line2)//字节数为奇数,那么我们将对其进行反转。
*行=反向(*行);
返回;
};
//现在我们必须从
对于(;line2>=行;line2--)
*tmp_buff++=(反向(line2[1])>>(8位_delta)|//这里的端点不确定!

(reverse(line2[0])我不知道.bmp文件是如何存储在内存中的,但在第一种方法中,我会做一些类似于(伪代码)的事情:


你不想把它翻过来,对吧?