• Welcome to Vampyre Imaging Library Forum. Please login or sign up.
 
21 November 2024, 18:18:31

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 - heju

1
Hi,

somehow, when loading a rgb bitmap with alpha channel and writing it back to bitmap the result is very blueish and the resulting bitmap has no alpha channel, seems as if the alpha channel is interpreted as blue somewhere.

img.CreateFromFile('rgb128alpha.bmp');
img.SaveToFile('out.bmp');


I checked the bytes after creating, here everything seems correct, problem should be in the save procedure.

When trying to save to PNG, the resulting png has alpha, but is blueish as well.

Hope I find some more time to give more detailed description...

Greetings&Bye
2
Hi,

when converting a rgb bmp with alpha channel to ifGray8, I noted that the pixel values in the final image are not as expected.

I think the problem could be here:
The source is read using PColor24Rec(Src), however in memory there is the alpha byte first (not the blue byte). Therefore the alpha channel is interpreted as blue channel. As the Src is incremented by 4 which is correct, the pixels do not get mixed up totally. 


procedure ChannelToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,
  DstInfo: PImageFormatInfo);
var
  I: LongInt;
  Pix64: TColor64Rec;
  Alpha: Word;
begin
  // two most common conversions (R8G8B8->Gray8 nad A8R8G8B8->Gray8)
  // are made separately from general conversions to make them faster
  if (SrcInfo.BytesPerPixel in [3, 4]) and (DstInfo.Format = ifGray8) then
    for I := 0 to NumPixels - 1 do
    begin
      Dst^ := Round(GrayConv.R * PColor24Rec(Src).R + GrayConv.G * PColor24Rec(Src).G +
        GrayConv.B * PColor24Rec(Src).B);
      Inc(Src, SrcInfo.BytesPerPixel);
      Inc(Dst, DstInfo.BytesPerPixel);
    end
  else 
[...]
                                 


One ugly workaround which just disregards the alpha channel is to increment Src by one before entering the loop in case we have 4 bytes per pixel, then the RGB values are not mixed up at least.

Greetings & bye
3
Hi,

while converting gray 8bit images to float 32bit and back to gray 8 bit I noted that the intensity values dramatically change:

"in128.bmp" is a grayscale bitmap with pixel values of 128

img.CreateFromFile('in128.bmp');
img.Format:=ifGray8;
img.Format:=ifR32F;
img.Format:=ifGray8;
img.SaveToFile('out.bmp');


Now in the "out.bmp" image the pixel values are only 38.

As this is a bit of a problem for my application, I investigated a bit: The root cause seems to be here:
procedure FloatToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,
  DstInfo: PImageFormatInfo);
var
  I: LongInt;
  PixF: TColorFPRec;
  Gray: TColor64Rec;
  Alpha: Word;
begin
  for I := 0 to NumPixels - 1 do
  begin
    FloatGetSrcPixel(Src, SrcInfo, PixF);
    ClampFloatPixel(PixF);

    // alpha is saved from source pixel to Alpha,
    // Gray value is computed and set to highest word of Pix64 so
    // Pix64.Color contains grayscale value scaled to 64 bits
    Alpha := ClampToWord(Round(PixF.A * 65535.0));
    Gray.A := ClampToWord(Round((GrayConv.R * PixF.R + GrayConv.G * PixF.G +
      GrayConv.B * PixF.B) * 65535.0));

    GraySetDstPixel(Dst, DstInfo, Gray, Alpha);
    Inc(Src, SrcInfo.BytesPerPixel);
    Inc(Dst, DstInfo.BytesPerPixel);
  end;
end;


Even the float image is single channel, the RGB-> gray conversion is calculated, reducing the pixel values (there is only intensity in red channel and this gets multiplied with GrayConv.R factor.

I workarounded the behaviour using the following approach (don't know if there are side effects). However now the value after conversion is the same as before:
(sry, you have to scroll down a bit maybe ;) )

procedure FloatToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,
  DstInfo: PImageFormatInfo);
var
  I: LongInt;
  PixF: TColorFPRec;
  Gray: TColor64Rec;
  Alpha: Word;
begin
  for I := 0 to NumPixels - 1 do
  begin
    FloatGetSrcPixel(Src, SrcInfo, PixF);
    ClampFloatPixel(PixF);

    // alpha is saved from source pixel to Alpha,
    // Gray value is computed and set to highest word of Pix64 so
    // Pix64.Color contains grayscale value scaled to 64 bits
    Alpha := ClampToWord(Round(PixF.A * 65535.0));
    if SrcInfo.ChannelCount =1 then
      Gray.A := ClampToWord(Round(PixF.R * 65535.0))
    else
      Gray.A := ClampToWord(Round((GrayConv.R * PixF.R + GrayConv.G * PixF.G +
        GrayConv.B * PixF.B) * 65535.0));

    GraySetDstPixel(Dst, DstInfo, Gray, Alpha);
    Inc(Src, SrcInfo.BytesPerPixel);
    Inc(Dst, DstInfo.BytesPerPixel);
  end;
end;


Bye...
4
Hi,

thanks for the fast response!

I gave ptr2int = ptruInt; a try: No obvious problems so far.
Would there be a kind of unit test for the library to confirm everything is ok after changing such small but maybe important things?

Btw I noticed another warning, this time in the jpeg code:
I always try to test run my code using all compiler checks on. I noticed that in the jpeg code a range check error is triggered in file imjdphuff.pas

Dec(entropy^.restarts_to_go); (several occurrences, the value to be decremented is zero)

Seems to be ok if
if entropy^.restarts_to_go >0 then

is added before these lines. However I did not have a closer look if this a good idea (maybe the underflow is somehow useful?


SMF spam blocked by CleanTalk