cancel
Showing results for 
Search instead for 
Did you mean: 

How to add images at runtime (jpg)

ADow.1
Associate II

I tried using the Jpeg Loader here: Loading Images at Runtime | TouchGFX Documentation

but when I use it it causes a hardfault in JPEGFileLoader::readJPEGFile -> jpeg_start_decompress -> master_selection -> jinit_d_main_controller -> (line 482) main = (my_main_ptr)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,SIZEOF(my_main_controller));

I found that the hardfault here is caused by the master_selection calling jinit_d_coef_controller  before jinit_d_main_controller, and in this function (jinit_d_coef_controller ) the "cinfo" variable gets destroyed in an "ERREXIT" (D_MULTISCAN_FILES_SUPPORTED is not defined in any file, and even if I define it manually it still hardfaults).

I don't know what the functions are actually supposed to do, and I don't know how to fix this.

Is there a workaround? or a new Loader file? (I downloaded the zip file from the documentation)

I'm attaching the hardfaulted function - jinit_d_main_controller, the jinit_d_coef_controller  , and how I'm calling the JpegLoader.

calling the JpegLoader in screenView.cpp:

 uint8_t lineBuffer[320*3]; //global
 
void Screen_1View::loadJpegImages(touchgfx::Image* image, const char* name, int x, int y)
{
 uint16_t width, height;
 
FS_FILE* f = FS_FOpen(name, "rb");
if (!f)
	return;
 JPEGFileLoader::getJPEGDimensions(f, width, height);
    
  BitmapId bmpId;
 
    //create dynamic bitmap matching file dimensions and in format matching LCD
    if (HAL::lcd().bitDepth() == 16)
    {
        bmpId = Bitmap::dynamicBitmapCreate(width, height, Bitmap::RGB565);
    }
    else
    {
        bmpId = Bitmap::dynamicBitmapCreate(width, height, Bitmap::RGB888);
    }
 
    if (bmpId != BITMAP_INVALID)
    {
        //Succesfully created, load JPEG file to bitmap
				if (file_type == FILE_TYPE_NONE)
					JPEGFileLoader::readJPEGFile(Bitmap(bmpId), f, lineBuffer);
    
				//Image shall show the loaded bitmap
				image->setBitmap(Bitmap(bmpId));
 
				//Position image and add to View
				image->setXY(x, y);
				add(*image);
				//image->invalidate();
		}
}

jinit_d_main_controller: (hardfault in line 😎

GLOBAL(void)
jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{
  my_main_ptr main;
  int ci, rgroup, ngroups;
  jpeg_component_info *compptr;
 
  main = (my_main_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				SIZEOF(my_main_controller));
  cinfo->main = (struct jpeg_d_main_controller *) main;
  main->pub.start_pass = start_pass_main;
 
  if (need_full_buffer)		/* shouldn't happen */
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
 
  /* Allocate the workspace.
   * ngroups is the number of row groups we need.
   */
  if (cinfo->upsample->need_context_rows) {
    if (cinfo->min_DCT_v_scaled_size < 2) /* unsupported, see comments above */
      ERREXIT(cinfo, JERR_NOTIMPL);
    alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
    ngroups = cinfo->min_DCT_v_scaled_size + 2;
  } else {
    ngroups = cinfo->min_DCT_v_scaled_size;
  }
 
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       ci++, compptr++) {
    rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
      cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
    main->buffer[ci] = (*cinfo->mem->alloc_sarray)
			((j_common_ptr) cinfo, JPOOL_IMAGE,
			 compptr->width_in_blocks * compptr->DCT_h_scaled_size,
			 (JDIMENSION) (rgroup * ngroups));
  }
}

jinit_d_coef_controller :

GLOBAL(void)
jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{
  my_coef_ptr coef;
 
  coef = (my_coef_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				SIZEOF(my_coef_controller));
  cinfo->coef = (struct jpeg_d_coef_controller *) coef;
  coef->pub.start_input_pass = start_input_pass;
  coef->pub.start_output_pass = start_output_pass;
#ifdef BLOCK_SMOOTHING_SUPPORTED
  coef->coef_bits_latch = NULL;
#endif
 
  /* Create the coefficient buffer. */
  if (need_full_buffer) {
#ifdef D_MULTISCAN_FILES_SUPPORTED
    /* Allocate a full-image virtual array for each component, */
    /* padded to a multiple of samp_factor DCT blocks in each direction. */
    /* Note we ask for a pre-zeroed array. */
    int ci, access_rows;
    jpeg_component_info *compptr;
 
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
	 ci++, compptr++) {
      access_rows = compptr->v_samp_factor;
#ifdef BLOCK_SMOOTHING_SUPPORTED
      /* If block smoothing could be used, need a bigger window */
      if (cinfo->progressive_mode)
	access_rows *= 3;
#endif
      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
	((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
				(long) compptr->h_samp_factor),
	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
				(long) compptr->v_samp_factor),
	 (JDIMENSION) access_rows);
    }
    coef->pub.consume_data = consume_data;
    coef->pub.decompress_data = decompress_data;
    coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
#else
    ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
  } else {
    /* We only need a single-MCU buffer. */
    JBLOCKROW buffer;
    int i;
 
    buffer = (JBLOCKROW)
      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
      coef->MCU_buffer[i] = buffer + i;
    }
    if (cinfo->lim_Se == 0)	/* DC only case: want to bypass later */
      FMEMZERO((void FAR *) buffer,
	       (size_t) (D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)));
    coef->pub.consume_data = dummy_consume_data;
    coef->pub.decompress_data = decompress_onepass;
    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
  }
}

Any help is appreciated!

1 ACCEPTED SOLUTION

Accepted Solutions

Hi MM

Thanks for the help, When I was watching the heap and stack sizes I noticed that the exit error I was getting was "Not a JPG format", apparently the image I had in my file system was only named *.jpg but in fact was a different type.

After switching it to a proper .jpg image I reach the third fail you mentioned before.

for future reference, the add should not be here, and the invalidate should be uncommented out.

View solution in original post

5 REPLIES 5
MM..1
Chief II

As first in normal you can call this load only from screensetup.

Second is linebufer ok size? Maybe jpeg need more as 320x3

Third fail is

add(*image);

Hi MM

The linebuffer is ok, I ran it in debug and it isn't even used before the hardfault.

The code doesn't even run until the third fail.

/Abeer

MM..1
Chief II

Check your heap and stack size for ...

Hi MM

Thanks for the help, When I was watching the heap and stack sizes I noticed that the exit error I was getting was "Not a JPG format", apparently the image I had in my file system was only named *.jpg but in fact was a different type.

After switching it to a proper .jpg image I reach the third fail you mentioned before.

for future reference, the add should not be here, and the invalidate should be uncommented out.

MM..1
Chief II

Helpfull is add to first message MCU used info and mark an reply as best for show thread as solved...