2014年8月24日日曜日

グレースケールその2

ループもアセンブラで書いた
void apply_grayscale(uint8_t* dstImg, uint8_t* srcImg, int pixelCount)
{
    uint16_t tmp1;
    int counter;

    __asm
    {
        mov ebx, srcImg
        mov ecx, pixelCount
        mov counter, 0
            
    loop0:
        mov tmp1, 0

        mov ah, 77                        // 0.298912 * 256
        mov al, [ebx+0]
        mul ah
        mov tmp1, ax

        mov ah, 150                        // 0.586611 * 256
        mov al, [ebx+1]
        mul ah
        add tmp1, ax

        mov ah, 29                        // 0.114478 * 256
        mov al, [ebx+2]
        mul ah
        add tmp1, ax
        
        shr tmp1, 8
        mov ax, tmp1

        push ebx
        mov ebx, dstImg
        add ebx, counter
        mov [ebx+0], al
        mov [ebx+1], al
        mov [ebx+2], al
        pop ebx

        add counter, 3
        add ebx, 3
        sub ecx, 3
        jnz loop0
    }
}
もうちょい短くなるのかな?

2014/08/24 18:31 追記
ちょっと短くなった
void apply_grayscale(uint8_t* dstImg, uint8_t* srcImg, int pixelCount)
{
    int counter;

    __asm
    {
        mov ebx, srcImg
        mov ecx, pixelCount
        mov counter, 0
            
    loop0:
        mov dx, 0

        mov ax, 77                        // 0.298912 * 256
        mul [ebx+0]
        mov dx, ax

        mov ax, 150                       // 0.586611 * 256
        mul [ebx+1]
        add dx, ax

        mov ax, 29                        // 0.114478 * 256
        mul [ebx+2]
        add dx, ax
        
        shr dx, 8

        push ebx
        mov ebx, dstImg
        add ebx, counter
        mov [ebx+0], dl
        mov [ebx+1], dl
        mov [ebx+2], dl
        pop ebx

        add counter, 3
        add ebx, 3
        sub ecx, 3
        jnz loop0
    }
}

2014年8月23日土曜日

グレースケール

初めて画像処理をアセンブラで書いてみた
アセンブラでロジックを書くのは初めてかな
#include <cstdint>
#include <fstream>

using namespace std;

int main()
{
    static const int IMG_HEADER_SIZE = 54;
    uint8_t* hdr = new uint8_t[IMG_HEADER_SIZE];
    memset(hdr, 0, IMG_HEADER_SIZE);

    static const int IMG_DATA_SIZE = 1024*768*3; 
    uint8_t* img = new uint8_t[IMG_DATA_SIZE];
    memset(img, 0, IMG_DATA_SIZE);

    ifstream input_file("C:\\Users\\xxxxx\\Desktop\\Desert.bmp", ios::binary);
    input_file.read(reinterpret_cast<char*>(hdr), IMG_HEADER_SIZE);
    input_file.read(reinterpret_cast<char*>(img), IMG_DATA_SIZE);

    for (int i = 0; i < IMG_DATA_SIZE; i+=3)
    {
        static const int GS_R8_WEIGHT = static_cast<int>(0.298912 * 256);
        static const int GS_G8_WEIGHT = static_cast<int>(0.586611 * 256);
        static const int GS_B8_WEIGHT = static_cast<int>(0.114478 * 256);

        uint8_t r8 = img[i+0];
        uint8_t g8 = img[i+1];
        uint8_t b8 = img[i+2];
        uint16_t tmp1;
        uint8_t result;

        __asm
        {
            mov tmp1, 0x00

            mov ah, 0
            mov al, r8
            mul GS_R8_WEIGHT
            mov tmp1, ax

            mov ah, 0
            mov al, g8
            mul GS_G8_WEIGHT
            add tmp1, ax

            mov ah, 0
            mov al, b8
            mul GS_B8_WEIGHT
            add tmp1, ax
        
            shr tmp1, 8
            push tmp1
            pop result
        }

        img[i+0] = result;
        img[i+1] = result;
        img[i+2] = result;
    }

    ofstream output_file("C:\\Users\\xxxxx\\Desktop\\Desert_grayscale.bmp", ios::binary);
    output_file.write(reinterpret_cast<char*>(hdr), IMG_HEADER_SIZE);
    output_file.write(reinterpret_cast<char*>(img), IMG_DATA_SIZE);
    output_file.close();

    delete[] hdr;
    delete[] img;

    return 0;
}

SQL で MP4 をパース

SQL でビットマップ画像の2値化は4年位前に挑戦した。 最近、それの Impala 版 を作ったときに閃いた。 「再帰CTEがあるなら、mp4 もいけるんじゃないか」と。 やってみた。 use ragingo drop table video go create...