• Welcome to Vampyre Imaging Library Forum. Please login or sign up.
 
23 November 2024, 13:39:24

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Patman

1
Windows 7 x64
Delphi RAD Studio 10.2
Vampyre Imaging latest snapshot
-----

Error occurs when adding mipmaps to MultiImage before exporting to DDS. Like this:

Code (pascal) Select
var
  LImage: TMultiImage;
  LImageCanvas: TImagingCanvas;
  LImageMipMaps: TDynImageDataArray;
begin
          ...
          LImage.Format := ifDXT5;
          Imaging.GenerateMipMaps(LImage.ImageDataPointer^, 10, LImageMipMaps);
          LImage.AddImages(LImageMipMaps);
          FreeImagesInArray(LImageMipMaps);
          LImage.SaveMultiToFile(ToDir + ToMaterial + '.dds');
          ...
end;


LImage has only 1 image when AddImages is called to add 10 mipmaps.
Getting range error from System.Move operation in ImagingClasses::PrepareInsert:

Code (pascal) Select
function TMultiImage.PrepareInsert(Index, Count: Integer): Boolean;
var
  I: Integer;
begin
  // Inserting to empty image will add image at index 0
  if GetImageCount = 0 then
    Index := 0;

  if (Index >= 0) and (Index <= GetImageCount) and (Count > 0) then
  begin
    SetLength(FDataArray, GetImageCount + Count);
    if Index < GetImageCount - 1 then
    begin
      // Move imges to new position
      System.Move(FDataArray[Index], FDataArray[Index + Count],
        (GetImageCount - Count - Index) * SizeOf(TImageData));
      // Null old images, not free them!
      for I := Index to Index + Count - 1 do
        InitImage(FDataArray[I]);
    end;
    Result := True;
  end
  else
    Result := False;
end;


The System.Move and InitImage loop are for handling insertions via InsertImage(s) procedures, but it is also executed for all AddImage(s) procedures, which always add to the end of the array.
I changed it to the following (not tested for all InsertImage(s) and AddImage(s) operations):

Code (pascal) Select
function TMultiImage.PrepareInsert(Index, Count: Integer): Boolean;
var
  I, LImageCount: Integer;
begin
  // Inserting to empty image will add image at index 0
  LImageCount := GetImageCount;
  if LImageCount = 0 then
    Index := 0;

  if (Index >= 0) and (Index <= LImageCount) and (Count > 0) then
  begin
    SetLength(FDataArray, LImageCount + Count);
    if Index <= LImageCount - 1 then
    begin
      // Move images to new position
      System.Move(FDataArray[Index], FDataArray[Index + Count], (GetImageCount - Count - Index) * SizeOf(TImageData));
      // Null old images; do not free them!
      for I := Index to Index + Count - 1 do
        InitImage(FDataArray[I]);
    end;
    Result := True;
  end
  else
    Result := False;
end;



Secondly, this appears to be a bug:

Code (pascal) Select
procedure TMultiImage.InsertImages(Index: Integer;
  const Images: TDynImageDataArray);
begin
  DoInsertImages(Index, FDataArray);
end;


Which should be:

Code (pascal) Select
procedure TMultiImage.InsertImages(Index: Integer;
  const Images: TDynImageDataArray);
begin
  DoInsertImages(Index, Images);
end;

2
ImagingCanvases.pas:

function TransformPremultiplyAlpha(const Pixel: TColorFPRec; P1, P2, P3: Single): TColorFPRec;
begin
  Result.A := Pixel.A;
  Result.R := Result.R * Pixel.A;
  Result.G := Result.G * Pixel.A;
  Result.B := Result.B * Pixel.A;
end;

function TransformUnPremultiplyAlpha(const Pixel: TColorFPRec; P1, P2, P3: Single): TColorFPRec;
begin
  Result.A := Pixel.A;
  if Pixel.A <> 0.0 then
  begin
    Result.R := Result.R / Pixel.A;
    Result.G := Result.G / Pixel.A;
    Result.B := Result.B / Pixel.A;
  end
  else
  begin
    Result.R := 0;
    Result.G := 0;
    Result.B := 0;
  end;
end;


IMHO the alpha operations on Result.R, Result.G and Result.B should be on Pixel.R, Pixel.G and Pixel.B:

function TransformPremultiplyAlpha(const Pixel: TColorFPRec; P1, P2, P3: Single): TColorFPRec;
begin
  Result.A := Pixel.A;
  Result.R := Pixel.R * Pixel.A;
  Result.G := Pixel.G * Pixel.A;
  Result.B := Pixel.B * Pixel.A;
end;

function TransformUnPremultiplyAlpha(const Pixel: TColorFPRec; P1, P2, P3: Single): TColorFPRec;
begin
  Result.A := Pixel.A;
  if Pixel.A <> 0.0 then
  begin
    Result.R := Pixel.R / Pixel.A;
    Result.G := Pixel.G / Pixel.A;
    Result.B := Pixel.B / Pixel.A;
  end
  else
  begin
    Result.R := 0;
    Result.G := 0;
    Result.B := 0;
  end;
end;


SMF spam blocked by CleanTalk