[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