[Issue 1081] New: with using real and -O option, dmd generate bug code
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Mar 27 00:21:36 PDT 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1081
Summary: with using real and -O option, dmd generate bug code
Product: D
Version: unspecified
Platform: PC
OS/Version: Windows
Status: NEW
Severity: normal
Priority: P2
Component: DMD
AssignedTo: bugzilla at digitalmars.com
ReportedBy: s180m at yahoo.co.jp
//dmd -release -inline -O で間違った動作をする。
//-Oを外すか、realをプログラムから追放すると、正しい動作。
import std.file;
import std.math;
import std.c.windows.windows;
import std.c.stdlib;
import std.outofmemory;
alias real Real;
align(1)
struct BGR24 {
ubyte blue , green , red;
const BGR24 Gray = {0xc0 , 0xc0 , 0xc0};
}
int clamp(int value,int min,int max){
if(value<min) return min;
if(value>max) return max;
return value;
}
BITMAPINFOHEADER* transform_(BITMAPINFOHEADER* src,Real angle){
int width = src.biWidth;assert(0==width % 4);///@note
bmpのpaddingを考慮していない。
int height = abs(src.biHeight);
BGR24* srcLines = cast(BGR24*)&src[1];
BITMAPINFOHEADER* result = cast(BITMAPINFOHEADER*)(new
ubyte[40+width*3*height]);
*result = *src;
BGR24* dstLines = cast(BGR24*)&result[1];
int width16 = width<<16;
int height16 = height<<16;
Coordinate coord;
coord.initY(src,angle);
for(int j;j<height;j++){
coord.initX();
for(int i;i<width;i++){
BGR24 pixel = BGR24.Gray;
if( (0<=coord.sa.x) && (0<=coord.sa.y) && (coord.sa.x<width16) &&
(coord.sa.y<height16) ) {
pixel = srcLines[(coord.sa.y>>16) * width + (coord.sa.x>>16)];
}
dstLines[j * width + i] = pixel;
coord.stepX();
}
coord.stepY();
}
return result;
}
BITMAPINFOHEADER* transform_L2(BITMAPINFOHEADER* src,Real angle){
int width = src.biWidth;assert(0==width % 4);///@note
bmpのpaddingを考慮していない。
int height = abs(src.biHeight);
BGR24* srcLines = cast(BGR24*)&src[1];
BITMAPINFOHEADER* result = cast(BITMAPINFOHEADER*)(new
ubyte[40+width*3*height]);
*result = *src;
BGR24* dstLines = cast(BGR24*)&result[1];
Coordinate coord;
coord.initY(src,angle);
for(int j;j<height;j++){
coord.initX();
for(int i;i<width;i++){
Info info;
POINT pos;
pos.x = coord.sa.x>>16;
pos.y = coord.sa.y>>16;
int fx_= (coord.sa.x & 0xffff) + 0x10000;
int fy = (coord.sa.y & 0xffff) + 0x10000;
for(int jj=pos.y-2;jj<pos.y+2;jj++,fy-=0x10000){
long w2 = cast(long)Lanczos2[fy];
for(int ii=pos.x-2,fx=fx_;ii<pos.x+2;ii++,fx-=0x10000){
long weight = cast(long)Lanczos2[fx] * w2;
info.step1(weight);
if( (0<=ii) && (0<=jj) && (ii<width) && (jj<height) ){
info.step2(srcLines[jj * width + ii],weight);
}
}
}
dstLines[j * width + i] = info.getPixel;
coord.stepX();
}
coord.stepY();
}
return result;
}
private struct Coordinate {
POINT dx,dy,sl,sa;
void initY(BITMAPINFOHEADER* src,Real angle) {
dx.x = cast(int)( cos(angle) * 65536.);
dx.y = cast(int)(-sin(angle) * 65536.);
dy.x =-dx.y;
dy.y = dx.x;
sl.x = 0;
sl.y = 0;
}
void initX(){sa = sl;}
void stepX(){sa.x += dx.x;sa.y += dx.y;}
void stepY(){sl.x += dy.x;sl.y += dy.y;}
}
private struct Info {
alias BGR24 T;
long b,g,r,d;
void step1(long weight){}
void step2(T pixel,long weight){
b+=pixel.blue * weight;
g+=pixel.green * weight;
r+=pixel.red * weight;
d+=weight;
}
T getPixel(){
if(0==d) return T.Gray;
T result;
result.blue = clamp(b/d,0,255);
result.green = clamp(g/d,0,255);
result.red = clamp(r/d,0,255);
return result;
}
}
abstract final class Lanczos2 {
private:
static int* s_table;
static this(){
s_table = cast(int*)malloc(int.sizeof * (2<<16));
if(! s_table) _d_OutOfMemory();
Real t =0;
for(int i=0;i<2<<16;i++){
t += 1./65536.;
s_table[i] = cast(int)round(
65536.*sin(PI*t)*sin(PI/2.*t)/((PI*PI/2.)*t*t) );
}
s_table[0] = 1<<16;
}
public:
static int opIndex(int a) {
if((a <= -2<<16) || (a >= 2<<16)) return 0;
if(a<0) a=-a;
assert((0<=a)&&(a<2<<16));
return s_table[a];
}
}
void main(){
ubyte[] src = cast(ubyte[])read("a.bmp");
BITMAPINFOHEADER* dst = transform_L2(cast(BITMAPINFOHEADER*)&src[14],PI/10.);
write("a_out.bmp",src[0..14] ~ (cast(ubyte*)dst)[0..src.length-14]);
}
--
More information about the Digitalmars-d-bugs
mailing list