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