2

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

我想澄清一下,我的 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);
}
4

1 回答 1

2

我很快就找到了我的问题的答案。现在我不使用 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){
   
       }
   }

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

于 2015-11-12T20:36:53.067 回答