jpeglibjpegqnxqnx-neutrinoblackberry-qnx

JPEG image on qnx window


I'm working on a project where I have jpg files and I have to show them on the QNX screen. I want to read a JPEG file using libjpeg and decode it and show it on qnx window using window pixmap. I tried writing my code as below but it responds with nothing. The screen stays black.

I want to make it clear that my JPEG file is in YCbCr (4.2.0 subsampled) but it doesn't matter really. JPEG file in sRGB format is fine too.

Here is my code looks like

#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <jpegint.h>

#ifdef __QNX__
#include <time.h>
#include <screen/screen.h>
#include <png.h>
#include <sys/netmgr.h>
#include <sys/neutrino.h>
#include <dirent.h>
#include <img/img.h>
#endif

screen_context_t screen_ctx;
screen_window_t screen_win;
screen_buffer_t screen_pbuf = 0;
screen_pixmap_t screen_pix;

int rect[4] = { 0, 0 };
int usage = 0;
screen_buffer_t screen_buf[2];



FILE *JPEG_open(char *filename)
{
   unsigned char c1, c2;
   FILE *fd = fopen(filename, "rb");
   if (fd != NULL)
   {
      c1 = fgetc(fd);
      c2 = fgetc(fd);
      if (c1 == 0xff && c2 == 0xd8)
         rewind(fd);
      else
      {
         fclose(fd);
         fd = NULL;
      }
   }
   return fd;
}


void JPEG_read_header(FILE *fd, int *pixtype, int *xdim, int *ydim)
{
   // JPEG declarations
   struct jpeg_decompress_struct dinfo;
   struct jpeg_error_mgr jerr;

   // Initialize the JPEG decompression object with default error handling
   dinfo.err = jpeg_std_error(&jerr);
   jpeg_create_decompress(&dinfo);
   jpeg_stdio_src(&dinfo, fd);

   // Read file header, set default decompression parameters
   jpeg_read_header(&dinfo, TRUE);
   jpeg_calc_output_dimensions(&dinfo);
   *xdim = dinfo.output_width;
   *ydim = dinfo.output_height;

   // Determine pixel type
   if (dinfo.out_color_space == JCS_GRAYSCALE){
      *pixtype = JPEG_GRAY;
      printf("Image format is - JPEG_GRAY");
   }
   else if(dinfo.out_color_space == JCS_YCbCr){
      printf("Image format is - JCS_YCbCr");
   }
   else{
      *pixtype = JPEG_RGB;
      printf("Image format is - JPEG_RGB");
   }

   // Close JPEG decompressor and input file
   jpeg_destroy_decompress(&dinfo);
   rewind(fd);
}

/*---------------------------------------------------------------------------*/
/* Purpose:  This reads JPEG data.                                           */
/*---------------------------------------------------------------------------*/
void JPEG_read_data(FILE *fd, char *data)
{
   // JPEG declarations
   struct jpeg_decompress_struct dinfo;
   struct jpeg_error_mgr jerr;
   JSAMPARRAY buffer;
   JSAMPROW ptr;
   int stride, row, value, index = 0;

   // Initialize the JPEG decompression object with default error handling
   dinfo.err = jpeg_std_error(&jerr);
   jpeg_create_decompress(&dinfo);
   jpeg_stdio_src(&dinfo, fd);

   // Read file header, set default decompression parameters
   jpeg_read_header(&dinfo, TRUE);
   printf("safjlasdfj");
   jpeg_calc_output_dimensions(&dinfo);
   jpeg_start_decompress(&dinfo);

   // Calculate number of samples per row in output buffer
   stride = dinfo.output_width * dinfo.output_components;
   buffer = (*dinfo.mem->alloc_sarray) ((j_common_ptr) & dinfo, JPOOL_IMAGE,(JDIMENSION) stride, (JDIMENSION) 1);

   // Process JPEG scanlines
   while (dinfo.output_scanline < dinfo.output_height)
   {
      jpeg_read_scanlines(&dinfo, buffer, 1);
      ptr = buffer[0];
      for (row = 0; row < stride; row++)
      {
         value = GETJSAMPLE(*ptr++);
         data[index++] = (unsigned char) value;
      }
   }

   // Finish decompression and release memory
   jpeg_finish_decompress(&dinfo);
   jpeg_destroy_decompress(&dinfo);
}





int main (int argc, char *argv[])
{

   printf("JPEG_read_data");

   screen_create_context(&screen_ctx, SCREEN_APPLICATION_CONTEXT);
   screen_create_window(&screen_win, screen_ctx);
   usage = SCREEN_USAGE_NATIVE;
   screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage);

   screen_create_window_buffers(screen_win, 2);
   screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, rect+2);
   screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)screen_buf);

   int bg[] = { SCREEN_BLIT_COLOR, 0x00000000, SCREEN_BLIT_END };
   screen_fill(screen_ctx, screen_buf[0], bg);

   int format = SCREEN_FORMAT_RGB888;
   int size[2] = {1280, 768};
   screen_create_pixmap(&screen_pix, screen_ctx); // TODO: Check failure
   screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_FORMAT, &format);
   usage = SCREEN_USAGE_WRITE | SCREEN_USAGE_NATIVE;
   screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_USAGE, &usage);
   screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_BUFFER_SIZE, size);
   screen_create_pixmap_buffer(screen_pix);

   char *realPixels;
   int realStride;
   screen_get_pixmap_property_pv(screen_pix, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)&screen_pbuf);
   screen_get_buffer_property_pv(screen_pbuf, SCREEN_PROPERTY_POINTER, (void **)&realPixels);
   //screen_get_buffer_property_iv(screen_pbuf, SCREEN_PROPERTY_STRIDE, &realStride);

   JPEG_read_data(JPEG_open("/usr/local/share/images/48.jpg"), realPixels);

   int hg[] = {
      SCREEN_BLIT_SOURCE_WIDTH, 1280,
      SCREEN_BLIT_SOURCE_HEIGHT, 768,
      SCREEN_BLIT_DESTINATION_X, 0,
      SCREEN_BLIT_DESTINATION_Y, 0,
      SCREEN_BLIT_DESTINATION_WIDTH, 1280,
      SCREEN_BLIT_DESTINATION_HEIGHT, 768,
      SCREEN_BLIT_TRANSPARENCY, SCREEN_TRANSPARENCY_SOURCE_OVER,
      SCREEN_BLIT_END
   };

   screen_blit(screen_ctx, screen_buf[0], screen_pbuf, hg);
   screen_post_window(screen_win, screen_buf[0], 1, rect, 0);
   while(1){
   }

   return (0);
}

Solution

  • I found the answer of my question really quickly. Now I don't use libjpeg and instead I use libimg which uses jpeg decoder (img_codec_jpg.so) and provide a generic api for all the decoders for qnx. here are the working code -

       #include <stdio.h>
       #include <stdlib.h>
       #include <jpeglib.h>
       #include <jpegint.h>
       
       #ifdef __QNX__
       #include <time.h>
       #include <screen/screen.h>
       #include <png.h>
       #include <sys/netmgr.h>
       #include <sys/neutrino.h>
       #include <dirent.h>
       #include <img/img.h>
       #endif
       
       screen_context_t screen_ctx;
       screen_window_t screen_win;
       const char* img_path = "usr/local/share/images/48.jpg"; /* Relative path to image asset */
       int viewport_size[2] = { 0, 0 };
       
       
       static int decode_setup(uintptr_t data, img_t *img, unsigned flags)
       {
           screen_window_t screen_win = (screen_window_t)data;
           screen_buffer_t screen_buf;
           int size[2];
       
           size[0] = img->w;
           size[1] = img->h;
           screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
           screen_create_window_buffers(screen_win, 1);
       
           screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&screen_buf);
           screen_get_buffer_property_pv(screen_buf, SCREEN_PROPERTY_POINTER, (void **)&img->access.direct.data);
           screen_get_buffer_property_iv(screen_buf, SCREEN_PROPERTY_STRIDE, (int *)&img->access.direct.stride);
       
           img->flags |= IMG_DIRECT;
           return IMG_ERR_OK;
       }
       
       static void decode_abort(uintptr_t data, img_t *img)
       {
           screen_window_t screen_win = (screen_window_t)data;
           screen_destroy_window_buffers(screen_win);
       }
       
       int load_image(screen_window_t screen_win, const char *path)
       {
           img_decode_callouts_t callouts;
           img_lib_t ilib = NULL;
           img_t img;
           int rc;
       
           rc = img_lib_attach(&ilib);
           if (rc != IMG_ERR_OK) {
              printf("Failed to load lib \n");
               return -1;
           }
       
           memset(&img, 0, sizeof(img));
           img.flags |= IMG_FORMAT;
           img.format = IMG_FMT_PKLE_XRGB8888;
       
           memset(&callouts, 0, sizeof(callouts));
           callouts.setup_f = decode_setup;
           callouts.abort_f = decode_abort;
           callouts.data = (uintptr_t)screen_win;
       
           rc = img_load_file(ilib, path, &callouts, &img);
           img_lib_detach(ilib);
       
           return rc == IMG_ERR_OK ? 0 : -1;
       }
       
       
       
       int main(int argc, char **argv)
       {
           const int usage = SCREEN_USAGE_WRITE;
       
           screen_buffer_t screen_buf = NULL;
           int rect[4] = { 0, 0, 0, 0 };
       
           /* Setup the window */
           screen_create_context(&screen_ctx, 0);
           screen_create_window(&screen_win, screen_ctx);
           screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage);
       
           load_image(screen_win, img_path);
       
           screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&screen_buf);
           screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, rect+2);
           viewport_size[0] = rect[2];
           viewport_size[1] = rect[3];
           screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE , viewport_size);
       
           screen_post_window(screen_win, screen_buf, 1, rect, 0);
       
       
           while(1){
       
           }
       }
    

    If it helped for you leave a comment. or let me know if you're still facing the problem. Thanks,Satish