• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Having trouble getting pixel data rather than NULL using PF_PixelPtr accessor macros

Community Beginner ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

Hi,

 

Just from the start I'm going to mention that I don't (or barely) know what I'm doing –so I apologize in advance for anything extra silly about my question. My code is cobbled together from attempts to understand the SDK's sample code, a slight memory of one quarter of C++ instruction decades past, questions lobbed at chatGPT (it's good at seeming confident even when wrong :), google searching to get clarity on mistakes, searches within this forum, etc. 

 

I'm trying to grab all the pixels from my PF_EffectWorld and copy them into a 2D array suitable for use with an algorithm that requires a table of pixels in that form. I've been banging against this a while, looking at the documentation for the PF_PixelPtr accessor macros and at the GLator sample code, and I think I've hit a wall and am not sure how to get past it. I am not finding a lot of information in the sample code or on the net for the use of  PF_GET_PIXEL_DATA8 and PF_GET_PIXEL_DATA16, but hopefully someone here understands this well-enough to easily spot my rookie mistake. Here's the relevant section of code that's stumping me:

 

static PF_Err
MySimplifiedPixelCopyingFunction (
                   PF_InData            *in_data,
                   PF_OutData           *out_data,
                   PF_ParamDef          *params[]                   )
{
PF_ParamDef            checkout;
PF_Err                 err = PF_Err_NONE;
PF_EffectWorld          *input_worldP = NULL;

    ERR(PF_CHECKOUT_PARAM(  in_data,
                            renderFileBridge_LAYER,
                            in_data->current_time,
                            in_data->time_step,
                            in_data->time_scale,
                            &checkout));

    
    if (!checkout.u.ld.data) {        // no input image

    } else {
        input_worldP = &checkout.u.ld;
        
        // Acquire a pointer to the pixel data
        PF_Pixel16 *pixel_dataP = NULL;
        PF_Pixel8 *pixel_data8P = NULL;
        if (input_worldP->world_flags & PF_WorldFlag_DEEP) {
            // Pixel data is in 16-bit format
            err = PF_GET_PIXEL_DATA16(input_worldP, NULL, &pixel_dataP);
        } else {
            // Pixel data is in 8-bit format
            err = PF_GET_PIXEL_DATA8(input_worldP, NULL, &pixel_data8P);
            
        }
        if (err != PF_Err_NONE) {
        // Handle the error
        }
        // Create an array to store the pixel values
        int num_pixels = input_worldP->width * input_worldP->height;
        PF_Pixel16 *pixel_values = new PF_Pixel16[num_pixels];
            
        // Copy the pixel values from the pixel data pointer to the array
        if (input_worldP->world_flags & PF_WorldFlag_DEEP) {
            // Copy the pixel values from the pixel data pointer to the array
            for (int i = 0; i < num_pixels; i++) {
                pixel_values[i] = pixel_dataP[i];
            }
        } else {
            // Copy the pixel values from the pixel data pointer to the array
            for (int i = 0; i < num_pixels; i++) {
                pixel_values[i].red = pixel_data8P[i].red << 8;

By this point in execution, I've run into the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x1)" on that last line, because as the debugger's variable view helpfully indicates, "pixel_data8P  = (PF_Pixel8 *) NULL".

 

Rewinding the tape a little, after PF_CHECKOUT_PARAM, the PF_ParamDef named "checkout" does indeed contain a PF_EffectWorld at checkout.u.ld. It contains data, and its width and height variable values match the width and height of the image in the layer that was checked out. 

 

My test for the pixel depth of input_worldP is either working, or failing, but either way because the image's pixels are 8-bit it is in this case resulting in the use of the right accessor macro, PF_GET_PIXEL_DATA8.

 

Unfortunately this is where everything clearly goes off the rails.

err = PF_GET_PIXEL_DATA8(input_worldP, NULL, &pixel_data8P);

The debugger's variable view helpfully tells me that after this line, "pixel_data8P = (PF_Pixel8 *) NULL". I think I've fed PF_GET_PIXEL_DATA8 a PF_EffectWorld full of image data, and I think I'm calling PF_GET_PIXEL_DATA8 correctly according to the documentation, but clearly I've made a blunder somewhere.

 

Because pixel_data8P is NULL, all further operations on it are doomed. Hopefully I'm doing something super-obviously-wrong and super-easily-fixable.

 

Thanks for any help, insights, jokes, etc. 

 

TOPICS
SDK

Views

268

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

I think I'm using the right accessor macro for this particular set of pixel data as I think it's in 8-bit format, but just in case I added a line so that right after it runs PF_GET_PIXEL_DATA8, it does a PF_GET_PIXEL_DATA16. e.g. 

            err = PF_GET_PIXEL_DATA8(input_worldP, NULL, &pixel_data8P);
            err = PF_GET_PIXEL_DATA16(input_worldP, NULL, &pixel_dataP);

But after those lines executed this time, both pixel_data8P and pixel_dataP are NULL. So that wasn't the issue. 

It's gotta be that I'm feeding the macro the wrong input, but I haven't yet figured out what's wrong about it.

 

I do see some examples in this forum in which people are using memcpy for this sort of thing, but I'm hoping to figure out how to do it using these accessors.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

Tried compiling and debugging GLator, with checkpoints marked a line before all the calls to PF_GET_PIXEL_DATA (8 and 16). I thought maybe I'd be able to see whether, in the one piece of sample code that uses the accessors, they were feeding them different inputs and outputs than I was. But unfortunately the debugger never stopped on those checkpoints and the plugin crashes at:

delete fragmentShaderAssemblyP;

 

To clarify -- I'm not really interested in getting GLator to run properly. I was just hoping to learn from it. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

I mis-spoke earlier -- PF_GET_PIXEL_DATA8 will return a pointer to a pixel, not return the pixel's data. So I'll still need to copy it myself. But the problem remains that I think pixel_data8P should nut be NULL after the call to the accessor but should point to a pixel. So my thought is that my input_worldP isn't valid, but I have not been able to yet figure out why.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

So I just noticed the following caveat in the documentation for the Interaction callback function PF_CHECKOUT_PARAM, "Do not check out layer parameters during UI event handling."

 

I am of course running PF_CHECKOUT_PARAM in a function that is triggered by a UI event - the user pressing a button. Even though I'm doing that, the function does seem to result in a bunch of data in the checkout variable, including a PF_EffectWorld or PF_LayerDef in checkout.u.ld. Hmm...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 27, 2023 Jan 27, 2023

Copy link to clipboard

Copied

LATEST

Hi,

I remember that you can only check out layer parameter in PF_Cmd_RENDER or PF_Cmd_SMART_PRERENDER, not sure enough.

And then, once you've got a PF_LayerDef* named layer, you can access it's pixels by the follow function:

PF_Pixel8* getPixel8P(const PF_LayerDef* layer, int x, int y) {
	if (layer) {
		if (x > -1 && y > -1 && x < layer->width && y < layer->height) {
			// each row of the input layer contains layer->rowbytes bytes, not layer->width * sizeof(PF_Pixel8)
			// because each end of a row has some padding, which idk what that means
			return (PF_Pixel8*)((char*)layer->data + (y * layer->rowbytes) + (x * sizeof(PF_Pixel8)));
		}
	}
	else return nullptr;
}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines