我正在做一个项目,我有jpg文件,必须在QNX屏幕上显示它们。我想使用libjpeg读取JPEG文件,并对其进行解码,然后使用window pixmap在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);
}
我很快就找到了问题的答案。现在我不使用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){
}
}
如果这对你有帮助,请留言。或者如果你仍然面临这个问题,请告诉我。谢谢,Satish