Picture.FromData gives immutableBitmap with hasAlphaChannel=true when HiDPI support is ON

See <https://xojo.com/issue/51923>

OS: OS X 10.12.6
Xojo: Xojo 2017r3

Regression: Yes

Steps: Run attached project

It loads a JPEG from data. The JPEG has only RGB color information (e.g. it’s RGB only, no alpha data).

When App.SupportHiDPI is ON,
the immutableBitmap returned has .hasAlphaChannel=True
this is contrary to the documentation : http://developer.xojo.com/hidpi-support$picture
which says that .HasAlphaChannel is “File-Specified”.

When App.SupportHiDPI is OFF
the mutableBitmap returned has .hasAlphaChannel=False, as expected.

Not a bug. See the first bullet under Picture Notes. If you need a mutable picture, use the CopyMask and CopyData methods.

Hi Greg, I think you misunderstand: the bug is that the .hasAlphaChannel value is always TRUE when App.SupportHiDPI is ON. The documents indicate it should be specified by the file, which, in practice, means that it will be True or False depending on whether the source file was 24 bit (RGB) or 32 bit (RGBA).

This is not academic. My app loads pictures, processes them, and then saves them, with an option of PNG or JPEG. Since JPEG can’t hold an alpha channel, it’s very important to know whether the original source file had alpha or not.

I can probably add a hack workaround, such as:

  • Use MBS plugins to open the file type header and parse it for alpha/no alpha
  • use the RGBSurface from Picture.CopyMask and scan all the pixels to see if any are non-zero.

But I think it would be better if Picture.hasAlphaChannel worked like it did before according to the documentation.

In conclusion, I think that this is not only a bug, it’s also a regression, which makes my bug report technically correct (the best kind!) :slight_smile:

Here is a workaround - it counts the number of non-blank pixels in the Mask, to determine if the source file did or did not have any alpha information.

It’s not terribly fast: benchmarking in a 64 bit build for macOS reveals it takes about 1000msec (one second) to process a 4096x4096 (16 megapixels) image. Smaller or larger images are proportionally faster/slower.

Public Function CountAlphaPixels(p as Picture) as integer
  // workaround for https://forum.xojo.com/47184-picture-fromdata-gives-immutablebitmap-with-hasalphachannel-tru/last
  
  dim t0 as double = Microseconds
  
  dim m as picture = p.CopyMask
  
  if m = nil then
    return 0
  end if
  
  dim r as RGBSurface = m.RGBSurface
  
  dim nNonBlankPixels as integer
  
  #Pragma BackgroundTasks False
  #Pragma BoundsChecking False
  #Pragma NilObjectChecking False
  
  dim xMax as integer = m.Width-1
  dim yMax as integer = m.Height-1
  
  dim result as boolean = false
  
  for y as integer = 0 to yMax
    for x as Integer = 0 to xMax
      dim c as color = r.Pixel(x,y)
      if c <> &c00000000 then
        nNonBlankPixels = nNonBlankPixels + 1
      end if
    next
  next
  
  dim deltaT as double = (Microseconds - t0)/1000
  system.debugLog CurrentMethodName + " took " + str(deltaT,"#") + " msec "
  return nNonBlankPixels

End Function