qnx 上的 JPEG 图片 window

JPEG image on qnx window

我正在做一个项目,我有 jpg 文件,我必须在 QNX 屏幕上显示它们。我想使用 libjpeg 读取 JPEG 文件并将其解码并使用 window 像素图在 qnx window 上显示它。 我尝试如下编写代码,但它没有任何响应。屏幕保持黑色。

我想说清楚我的 JPEG 文件是在 YCbCr(4.2.0 子采样)中,但这并不重要。 sRGB 格式的 JPEG 文件也可以。

这是我的代码

#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);
}

我很快就找到了问题的答案。现在我不使用 libjpeg,而是使用 libimg,它使用 jpeg 解码器 (img_codec_jpg.so) 并为 qnx 的所有解码器提供通用 api。这是工作代码-

   #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){
   
       }
   }

如果对您有帮助,请留下评论。或者让我知道您是否仍然面临问题。 谢谢,萨蒂什