拡大縮小(7)
で、同様にして Y 軸もループさせる。
この場合は +1 というのは 1line になる。
あと、昨日の sr は 0 から開始したけど、それだと縮小するときに左側のドットしか取れなくなってしまうので、を開始値とする。
それを踏まえた上で実装すると、こうなる。
void Palette8_To_RGB565_TransparentStretch( word* dst , // 転送先(RGB565) int dx , // 転送先 X 座標 int dy , // 転送先 Y 座標 int dp , // 転送先 pitch byte* src , // 転送元(8bit インデックス) int sx , // 転送元 X 座標 int sy , // 転送元 Y 座標 int sp , // 転送元 pitch int sw , // 転送元 width int sh , // 転送元 height word* pal , // パレット(RGB565) int key , // 透過インデックス int zw , // 横の拡大率(256 → 等倍 , 512 → 2倍) int zh // 縦の拡大率(256 → 等倍 , 512 → 2倍) ){ // 転送先の width , height を計算 int dw = (sw * zw) >> 8; int dh = (sh * zh) >> 8; // 転送先の X 座標、Y 座標を再計算 dx += (sw - dw) >> 1; dy += (sh - dh) >> 1; // 転送元、転送先を転送開始座標に移動 src = (byte*)((byte*)src + sx * sizeof( byte ) + sy * sp ); dst = (word*)((byte*)dst + dx * sizeof( word ) + dy * dp ); int js = 0; // 転送元の Y 軸の走査位置 int jd = 0; // 転送先の Y 軸の走査位置 int jv = sh / dh; // 転送元の毎ループ足す値 int ja = sh % dh; // 転送元の毎ループ足す誤差の値 int je = dh / 2; // 誤差 // jd は毎回移動、js は誤差が貯まったら移動 while( true ){ // Y の終了判定 if( jd >= dh ) break; // ここから 1line 転送 int is = 0; // 転送元の X 軸の走査位置 int id = 0; // 転送先の X 軸の走査位置 int iv = sw / dw; // 転送元の毎ループ足す値 int ia = sw % dw; // 転送元の毎ループ足す誤差の値 int ie = dw / 2; // 誤差 // id は毎回移動、is は誤差が貯まったら移動 while( true ){ // X の終了判定 if( id >= dw ) break; // ここから 1pixel 転送 if( src[ is ] != key ){ dst[ id ] = pal[ src[ is ] ]; } // ここまで 1pixel 転送 // id,is を移動させる id++; // 1 pixel 移動 is += iv; // iv pixel 移動 ie += ia; // 誤差を加算 if( ie > dw ){ // 誤差が dw を超えたら is++; // 1 pixel 移動 ie -= dw; } } // ここまで 1line 転送 jd++; dst = (word*)((byte*)dst + dp); // 1 line 移動 src = (byte*)((byte*)src + sp * jv); // jv line 移動 je += ja; // 誤差を加算 if( je > dh ){ // 誤差が dh を超えたら src = (byte*)((byte*)src + sp ); // 1 line 移動 je -= dh; } } }
でも、これはクリッピングを行っていないので、dst が領域外に出ると、アクセス違反になる。