Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#202 closed enhancement (wontfix)

Possibility for an Application/Objects to not use pictures global cache

Reported by: Guillaume Boesel Owned by:
Priority: normal Milestone: 4.0-2015R2
Component: Imagespace.mui Version: 4.0-nightly build
Severity: minor Keywords:
Cc: OS Platform: AmigaOS4
Blocked By: Blocking:
Release Notes:

Description

Problem

I build a program that use littles pictures in a list.

When I change the contents of these pictures by rotating them for example and by keeping the same filenames, the MUI pictures are not changed.

Even if I DOS unlock thess files (by using the LockDosList), and that I restart my program, the MUI pictures are not modified.

I understood that MUI programs use a global buffer for pictures as you explained here
https://muidev.de/ticket/200#comment:3

But could it be possible for a program or for an object to DON'T use this buffer ?

Thank you by advance for your time to examine this request.
Guillaume

Change History (7)

comment:1 Changed 5 years ago by Thore Böckelmann

Component: Application.muiImagespace.mui
Milestone: 4.0-2015R2
Priority: undecidednormal
Resolution: wontfix
Status: newclosed

MUI's image cache is meant for static images used in a GUI, not for presenting constantly modified images in an image view/manipulation application.

If you need this kind of feature then you are far better off with a custom class which loads the images itself and does all the fancy effects like the desired rotation. This also makes it possible to display the image with an arbitrary size by scaling. MUI's image cache can provide full size images only which might be too big to be displayed completely without a surrounding Scrollgroup object.

Bottom line: implementing a "skip cache" option is not worth the effort. Better use a custom class. This will let you do far more fancy stuff than MUI can provide internally.

comment:2 Changed 5 years ago by Thore Böckelmann

For thumbnails shown in a list object you can also use "\033A[address of ARGB image]" in the list item's text. Just fill a MUI_AlphaData structure with suitable data and put its address in the text to be displayed. These kind of images are never cached, because there is no loading process involved from MUI's point of view. Rotating the image just requires you to update the MUI_AlphaData structure and redrawing the corresponding list entry.

comment:3 Changed 5 years ago by Guillaume Boesel

Thank you for your replies.
It's not only rotating, it's too a lot of effects that can be applied to the original pictures and, therefore, to the thumbnailed pictures using LibDevIL.

But if I can load the picture, and fill a MUI_AlphaData structure (with a Bitmap structure ?) it will be nice !

I didn't find MUI_AlphaData "\033A" in the AutoDocs, do you have more informations ?
Thanks

comment:4 Changed 5 years ago by Thore Böckelmann

All the basics about MUI's text engine are explained in the Autodocs of MUIA_Text_Contents.

This is the structure you need to fill:

struct MUI_AlphaData
{
	LONG width;
	LONG height;
	LONG dummy[2]; // 16-byte align for data
	ULONG data[0];
};

The data field is an array of raw uncompressed 32bit ARGB values, no bitmap or whatsoever.

A 2x2 image might look like this:

struct MUI_AlphaData myimage =
{
  2, // width
  2, // height
  { 0, 0 }, // dummy
  // and now the raw ARGB image data, 2x2=4 values
  { 0xffffffff, 0xccff0000, 0xccff0000, 0x8800ff00 }
};

This structure will then be used like this

char buffer[32];
snprintf(buffer, sizeof(buffer), "\033A[%08lx]", &myimage);
set(obj, MUIA_Text_Contents, buffer);

Please keep in mind that the structure must be kept alive as long as the text buffer which references it is used by the text object. The structure will be accessed when ever the text objects needs to redraw itself.

comment:5 Changed 5 years ago by Guillaume Boesel

Thanks for explanations.
But is there a way to transform a picture file into an ARGB image data ?

Sorry for my low knowledge…

comment:6 Changed 5 years ago by Thore Böckelmann

You can instruct datatypes.library to read the raw ARGB data to a sufficiently large allocated buffer pixelArray:

success = DoMethod(dtobj, PDTM_READPIXELARRAY, pixelArray, PBPAFMT_ARGB, width*4, 0, 0, width, height);

Note that this call might fail, so better check the returned value. As a fallback you will have to process each pixel of a bitmap separately and convert it to ARGB data using the color map and a possibly existing mask plane. Something like this:

#define RGB_TO_ARGB(r,g,b) (((r)<<16) | ((g)<<8) | (b))

struct MUI_AlphaData *BitMapToAlphaData(struct BitMap *bm, struct BitMap *mask, struct ColorRegister *colors, LONG w, LONG h)
{
  struct MUI_AlphaData *ad = NULL;

  if(bm != NULL && colors != NULL)
  {
    // allocate some memory and blit the bitmap to it converting it to ARGB data
    if((ad = AllocVec(sizeof(struct MUI_AlphaData) + w*h*sizeof(ULONG), MEMF_ANY)) != NULL)
    {
      struct RastPort rp;
      LONG y;
      ULONG *argbp = ad->data;

      ad->width = width; 
      ad->height = height;

      memset(&rp, 0, sizeof(rp));
      InitRastPort(&rp);
      rp.BitMap = bm;

      if(mask != NULL)
      {
        PLANEPTR maskPlane = mask->Planes[0];

        for(y = 0; y < h; y++)
        {
          LONG x;
          UBYTE bitMask = 0x80;
          UBYTE *maskp = &maskPlane[RASSIZE(w,1) * y];

          for(x = 0; x < w; x++)
          {
            if((*maskp & bitMask) == 0)
            {
              *argbp++ = 0x00000000;
            }
            else
            {
              LONG pen = ReadPixel(&rp, x, y);

              *argbp++ = 0xff000000 | RGB_TO_ARGB(colors[pen].red, colors[pen].green, colors[pen].blue);
            }

            bitMask >>= 1;
            if(bitMask == 0x00)
            {
              bitMask = 0x80;
              maskp++;
            }
          }
        }
      }
      else
      {
        for(y = 0; y < h; y++)
        {
          LONG x;

          for(x = 0; x < w; x++)
          {
            LONG pen = ReadPixel(&rp, x, y);

            *argbp++ = 0xff000000 | RGB_TO_ARGB(colors[pen].red, colors[pen].green, colors[pen].blue);
          }
        }
      }
    }
  }

  return ad;
}

comment:7 Changed 5 years ago by Guillaume Boesel

Super !
It's very nice to explain all these things,

Many thanks, again.
Guillaume

Note: See TracTickets for help on using tickets.