Konwersja z delphi na C++ kodu do tworzenie miniatur

0

Witam, mam problem, próbuje przepisać kod z delphi na buildera C++ ale mam z tym spory problem i nie działa tak jak powinien problem mam z pt, zamieniłem RowDest, RowSource, RowSourceStart na Byte* ale wychodzi poza zakresy

procedure MakeThumbNail(Src, Dst: TBitmap);
var
  x, y, ix, iy, w, h, dx, dy: Integer;
  x1, x2, x3: integer;
  RowDest, RowSource, RowSourceStart: Integer;
  iRatio: Integer;
  Ratio: Single;
  iRed, iGrn, iBlu: Integer;
  pt: PRGB24;
  iSrc, iDst: Integer;
  lutW, lutH: array of Integer;
begin
  if (Src.Width <= Dst.Width) and (Src.Height <= Dst.Height) then begin
    Dst.Assign(Src);
    Exit;
  end;
  w := Dst.Width;
  h := Dst.Height;
  Ratio:= 1 / (w / Src.Width);
  SetLength(lutW, w);
  x1 := 0;
  x2 := Trunc(Ratio);
  for x := 0 to w - 1 do begin
    lutW[x] := x2 - x1;
    x1 := x2;
    x2 := Trunc((x + 2) * Ratio);
  end;
  Ratio:= 1 / (h / Src.Height);
  SetLength(lutH, h);
  x1 := 0;
  x2 := Trunc(Ratio);
  for x := 0 to h - 1 do begin
    lutH[x] := x2 - x1;
    x1 := x2;
    x2 := Trunc((x + 2) * Ratio);
  end;
  RowDest := Integer(Dst.Scanline[0]);
  RowSourceStart := integer(Src.Scanline[0]);
  RowSource := RowSourceStart;
  iDst := ((w * 24 + 31) and not 31) shr 3;
  iSrc := ((Src.Width * 24 + 31) and not 31) shr 3;
  for y := 0 to h - 1 do begin
    dy := lutH[y];
    x1 := 0;
    x3 := 0;
    for x := 0 to w - 1 do begin
      dx := lutW[x];
      iRed := 0;
      iGrn := 0;
      iBlu := 0;
      RowSource := RowSourceStart;
      for iy := 1 to dy do begin
        pt := PRGB24(RowSource + x1);
        for ix := 1 to dx do begin
          iRed := iRed + pt.R;
          iGrn := iGrn + pt.G;
          iBlu := iBlu + pt.B;
          inc(pt);
        end;
        RowSource := RowSource - iSrc;
      end;
      iRatio := $00FFFFFF div (dx * dy);
      pt := PRGB24(RowDest + x3);
      pt.R := (iRed * iRatio) shr 24;
      pt.G := (iGrn * iRatio) shr 24;
      pt.B := (iBlu * iRatio) shr 24;
      x1 := x1 + 3 * dx;
      inc(x3, 3);
    end;
    RowDest := RowDest - iDst;
    RowSourceStart := RowSource;
  end;
end;

mój kod niestety zły, pisany na bardzo szybko:

#define round(a) int((a)+0.5)

struct TRGB24
{
  Byte B;
  Byte G;
  Byte R;
};
typedef TRGB24* PRGB24;

void __fastcall MakeThumbNail(Graphics::TBitmap *Src, Graphics::TBitmap *Dst)
{
  if ((Src->Width <= Dst->Width) && (Src->Height <= Dst->Height))
  {
    Dst->Assign(Src);
    return;
  }

  int x, y, w, h, x1, x2, x3, dx, dy, iDst, iSrc;
  Byte *rowDest, *rowSourceStart, *rowSource;
  double ratio;

  w = Dst->Width;
  h = Dst->Height;
  ratio = 1 / (static_cast<double>(w) / static_cast<double>(Src->Width));

  int *lutW = new int[w];

  x1 = 0;
  x2 = round(ratio);

  for (x = 0; x < w; x++)  //-1
  {
    lutW[x] = x2 - x1;
    x1 = x2;
    x2 = round(static_cast<double>(x + 2) * ratio);
  }

  ratio = 1 / (static_cast<double>(h) / static_cast<double>(Src->Height));
  int *lutH = new int[h];

  x1 = 0;
  x2 = round(ratio);

  for (x = 0; x < h; x++) //-1
  {
    lutH[x] = x2 - x1;
    x1 = x2;
    x2 = round(static_cast<double>(x + 2) * ratio);
  }

  rowDest = (Byte*)Dst->ScanLine[0];
  rowSourceStart = (Byte*)Src->ScanLine[0];
  rowSource = rowSourceStart;

  iDst = ((w * 24 + 31) & ~31) >> 3;
  iSrc = ((Src->Width * 24 + 31) & ~31) >> 3;

  int iRed, iGrn, iBlu;
  PRGB24 pt;
  int iy, ix, iRatio;

  for (y = 0; y < h; y++)
  {
    dy = lutH[y];
    x1 = 0;
    x3 = 0;
    for (x = 0; x < w; x++)
    {
       dx = lutW[x];
       iRed = 0;
       iGrn = 0;
       iBlu = 0;
       rowSource = rowSourceStart;
       for (iy = 1; iy < dy; iy++)
       {
         pt = PRGB24(rowSource + x1);
         for (ix = 1; ix < dx; ix++)
         {
           iRed += pt->R;
           iGrn += pt->G;
           iBlu += pt->B;
           pt++;
         }
         rowSource = rowSource + iSrc;
       }

       iRatio = 0xFFFFFF / (dx * dy);
       pt = PRGB24(rowDest + x3);
       pt->R = (iRed * iRatio) >> 24;
       pt->G = (iGrn * iRatio) >> 24;
       pt->B = (iBlu * iRatio) >> 24;
       x1 = x1 + 3 * dx;

       x3 += 3;
    }

    rowDest = rowDest - iDst;
    rowSourceStart = rowSource;
  }
  delete []lutW;
  delete []lutH;
}

Pomożecie?

0

normalnie dołącz .pas i już

0

zależy mi tylko na jednej funkcji z pliku pas, resztę mam w C++ wiec wolę to przepisać i tu utknąłem :/

0

Tranc to nie round.

W c piszesz to zwyczajnie:
int n = x; // = tranc(x) z pascala

int n = x + 0.5; // a to jest round(x) z pascala

0

Jak wywołać funkcje z pliku pas po dołączeniu go do buildera? hpp jest stworzony przy kompilacji, include <nazwa.hpp> dodany ale funkcji nie widzi.

0
yabolik napisał(a):

Jak wywołać funkcje z pliku pas po dołączeniu go do buildera? hpp jest stworzony przy kompilacji, include <nazwa.hpp> dodany ale funkcji nie widzi.

O ile pamiętam tam nie ma nic do roboty: dołączasz cały ten plik .pas do projektu i tyle.
Tam zostanie wygenerowany automatycznie jakiś header, no a kod pozostanie w pas...
bo jedynie obj będzie linkowany finalnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1