void * bitmap_realloc( int w, int h, short bpp, int rowstride, unsigned int state, void * bmp ) { struct bitmap * bitmap = bmp; int newsize = rowstride * h; if( bitmap == NULL ) { return( NULL ); } assert( bitmap->pixdata != NULL ); int oldsize = bitmap->rowstride * bitmap->height; bool doalloc = (state & BITMAP_GROW) ? (newsize > oldsize) : (newsize != oldsize); if( newsize > oldsize ) assert( doalloc == true ); if( doalloc ) { // TODO: set red band to a specific value and check the red band // on bitmap_destroy() bitmap->pixdata = realloc( bitmap->pixdata, newsize + 128 ); if( bitmap->pixdata == NULL ) return( NULL ); } if( state & BITMAP_CLEAR ){ memset( bitmap->pixdata, 0x00, newsize + 128 ); } bitmap->width = w; bitmap->height = h; bitmap->bpp = bpp; bitmap->resized = NULL; bitmap->rowstride = rowstride; bitmap_modified( bitmap ); return( bitmap ); }
static bool nspng_convert(struct content *c) { nspng_content *png_c = (nspng_content *) c; char *title; assert(png_c->png != NULL); assert(png_c->info != NULL); /* clean up png structures */ png_destroy_read_struct(&png_c->png, &png_c->info, 0); /* set title text */ title = messages_get_buff("PNGTitle", nsurl_access_leaf(llcache_handle_get_url(c->llcache)), c->width, c->height); if (title != NULL) { content__set_title(c, title); free(title); } if (png_c->bitmap != NULL) { bitmap_set_opaque(png_c->bitmap, bitmap_test_opaque(png_c->bitmap)); bitmap_modified(png_c->bitmap); } image_cache_add(c, png_c->bitmap, png_cache_convert); content_set_ready(c); content_set_done(c); content_set_status(c, ""); return true; }
bool nsico_convert(struct content *c) { struct bmp_image *bmp; bmp_result res; ico_collection *ico; union content_msg_data msg_data; const char *data; unsigned long size; char title[100]; /* set the ico data */ ico = c->data.ico.ico; data = content__get_source_data(c, &size); /* analyse the ico */ res = ico_analyse(ico, size, (unsigned char *) data); switch (res) { case BMP_OK: break; case BMP_INSUFFICIENT_MEMORY: msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; case BMP_INSUFFICIENT_DATA: case BMP_DATA_ERROR: msg_data.error = messages_get("BadICO"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } /* Store our content width and description */ c->width = ico->width; c->height = ico->height; snprintf(title, sizeof(title), messages_get("ICOTitle"), c->width, c->height, size); content__set_title(c, title); c->size += (ico->width * ico->height * 4) + 16 + 44; /* exit as a success */ bmp = ico_find(c->data.ico.ico, 255, 255); assert(bmp); c->bitmap = bmp->bitmap; bitmap_modified(c->bitmap); c->status = CONTENT_STATUS_DONE; /* Done: update status bar */ content_set_status(c, ""); return true; }
void * bitmap_realloc( int w, int h, short bpp, int rowstride, unsigned int state, void * bmp ) { struct bitmap * bitmap = bmp; int newsize = rowstride * h; if( bitmap == NULL ) { return( NULL ); } if( bitmap->pixdata == NULL ) { assert( 1 == 0 ); /* add some buffer for bad code */ bitmap->pixdata = malloc( newsize + 128 ); bitmap->opaque = false; } else { int oldsize = bitmap->rowstride * bitmap->height; bool doalloc = ( state == BITMAP_GROW) ? (newsize > oldsize) : (newsize != oldsize); if( newsize > oldsize ) assert( doalloc == true ); if( doalloc ) { bitmap->pixdata = realloc( bitmap->pixdata, newsize + 128 ); if( bitmap->pixdata == NULL ) return( NULL ); } } if( state & BITMAP_CLEAR ){ memset( bitmap->pixdata, 0x00, newsize + 128 ); } bitmap->width = w; bitmap->height = h; bitmap->bpp = bpp; bitmap->resized = NULL; bitmap->rowstride = rowstride; bitmap_modified( bitmap ); return( bitmap ); }
static struct bitmap * jpeg_cache_convert(struct content *c) { uint8_t *source_data; /* Jpeg source data */ unsigned long source_size; /* length of Jpeg source data */ struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; jmp_buf setjmp_buffer; unsigned int height; unsigned int width; struct bitmap * volatile bitmap = NULL; uint8_t * volatile pixels = NULL; size_t rowstride; struct jpeg_source_mgr source_mgr = { 0, 0, nsjpeg_init_source, nsjpeg_fill_input_buffer, nsjpeg_skip_input_data, jpeg_resync_to_restart, nsjpeg_term_source }; /* obtain jpeg source data and perfom minimal sanity checks */ source_data = (uint8_t *)content__get_source_data(c, &source_size); if ((source_data == NULL) || (source_size < MIN_JPEG_SIZE)) { return NULL; } /* setup a JPEG library error handler */ cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = nsjpeg_error_exit; jerr.output_message = nsjpeg_error_log; /* handler for fatal errors during decompression */ if (setjmp(setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); return bitmap; } jpeg_create_decompress(&cinfo); cinfo.client_data = &setjmp_buffer; /* setup data source */ source_mgr.next_input_byte = source_data; source_mgr.bytes_in_buffer = source_size; cinfo.src = &source_mgr; /* read JPEG header information */ jpeg_read_header(&cinfo, TRUE); /* set output processing parameters */ cinfo.out_color_space = JCS_RGB; cinfo.dct_method = JDCT_ISLOW; /* commence the decompression, output parameters now valid */ jpeg_start_decompress(&cinfo); width = cinfo.output_width; height = cinfo.output_height; /* create opaque bitmap (jpegs cannot be transparent) */ bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE); if (bitmap == NULL) { /* empty bitmap could not be created */ jpeg_destroy_decompress(&cinfo); return NULL; } pixels = bitmap_get_buffer(bitmap); if (pixels == NULL) { /* bitmap with no buffer available */ bitmap_destroy(bitmap); jpeg_destroy_decompress(&cinfo); return NULL; } /* Convert scanlines from jpeg into bitmap */ rowstride = bitmap_get_rowstride(bitmap); do { JSAMPROW scanlines[1]; #if RGB_RED != 0 || RGB_GREEN != 1 || RGB_BLUE != 2 || RGB_PIXELSIZE != 4 int i; scanlines[0] = (JSAMPROW) (pixels + rowstride * cinfo.output_scanline); jpeg_read_scanlines(&cinfo, scanlines, 1); /* expand to RGBA */ for (i = width - 1; 0 <= i; i--) { int r = scanlines[0][i * RGB_PIXELSIZE + RGB_RED]; int g = scanlines[0][i * RGB_PIXELSIZE + RGB_GREEN]; int b = scanlines[0][i * RGB_PIXELSIZE + RGB_BLUE]; scanlines[0][i * 4 + 0] = r; scanlines[0][i * 4 + 1] = g; scanlines[0][i * 4 + 2] = b; scanlines[0][i * 4 + 3] = 0xff; } #else scanlines[0] = (JSAMPROW) (pixels + rowstride * cinfo.output_scanline); jpeg_read_scanlines(&cinfo, scanlines, 1); #endif } while (cinfo.output_scanline != cinfo.output_height); bitmap_modified(bitmap); jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return bitmap; }
static bool rsvg_convert(struct content *c) { rsvg_content *d = (rsvg_content *) c; union content_msg_data msg_data; RsvgDimensionData rsvgsize; GError *err = NULL; if (rsvg_handle_close(d->rsvgh, &err) == FALSE) { LOG(("rsvg_handle_close returned an error: %s", err->message)); msg_data.error = err->message; content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } assert(err == NULL); /* we should now be able to query librsvg for the natural size of the * graphic, so we can create our bitmap. */ rsvg_handle_get_dimensions(d->rsvgh, &rsvgsize); c->width = rsvgsize.width; c->height = rsvgsize.height; if ((d->bitmap = bitmap_create(c->width, c->height, BITMAP_NEW)) == NULL) { LOG(("Failed to create bitmap for rsvg render.")); msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } if ((d->cs = cairo_image_surface_create_for_data( (unsigned char *)bitmap_get_buffer(d->bitmap), CAIRO_FORMAT_ARGB32, c->width, c->height, bitmap_get_rowstride(d->bitmap))) == NULL) { LOG(("Failed to create Cairo image surface for rsvg render.")); msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } if ((d->ct = cairo_create(d->cs)) == NULL) { LOG(("Failed to create Cairo drawing context for rsvg render.")); msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } rsvg_handle_render_cairo(d->rsvgh, d->ct); rsvg_argb_to_abgr(bitmap_get_buffer(d->bitmap), c->width, c->height, bitmap_get_rowstride(d->bitmap)); bitmap_modified(d->bitmap); content_set_ready(c); content_set_done(c); /* Done: update status bar */ content_set_status(c, ""); return true; }
bool amiga_icon_convert(struct content *c) { amiga_icon_content *icon_c = (amiga_icon_content *)c; union content_msg_data msg_data; struct DiskObject *dobj; ULONG *imagebuf; unsigned char *imagebufptr = NULL; ULONG size; int width = 0, height = 0; long format = 0; int err = 0; uint8 r, g, b, a; ULONG offset; const char *url; char *filename; char *p; ULONG trans, pals1; struct ColorRegister *pal1; url = nsurl_access(content_get_url(c)); filename = url_to_path(url); /* This loader will only work on local files, so fail if not a local path */ if(filename == NULL) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } p = strstr(filename, ".info"); *p = '\0'; dobj = GetIconTagList(filename, NULL); if(dobj == NULL) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } err = IconControl(dobj, ICONCTRLA_GetImageDataFormat,&format, ICONCTRLA_GetWidth,&width, ICONCTRLA_GetHeight,&height, TAG_DONE); /* Check icon is direct mapped (truecolour) or palette-mapped colour. We need additional code to handle planar icons */ if((format != IDFMT_DIRECTMAPPED) && (format==IDFMT_PALETTEMAPPED)) { if(dobj) FreeDiskObject(dobj); return false; } icon_c->bitmap = bitmap_create(width, height, BITMAP_NEW); if (!icon_c->bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); if(dobj) FreeDiskObject(dobj); return false; } imagebuf = (ULONG *) bitmap_get_buffer(icon_c->bitmap); if (!imagebuf) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); if(dobj) FreeDiskObject(dobj); return false; } err = IconControl(dobj, ICONCTRLA_GetImageData1, &imagebufptr, TAG_DONE); if(format==IDFMT_PALETTEMAPPED) { IconControl(dobj, ICONCTRLA_GetTransparentColor1, &trans, ICONCTRLA_GetPalette1, &pal1, ICONCTRLA_GetPaletteSize1, &pals1, TAG_DONE); imagebufptr = (unsigned char *) amiga_icon_convertcolouricon32((UBYTE *)imagebufptr, width, height, trans, pals1, pal1, 0xff); } /* Decoded data is ARGB, so ensure correct byte order */ size = width * height * 4; for (offset = 0; offset < size; offset += 4) { b = imagebufptr[offset+3]; g = imagebufptr[offset+2]; r = imagebufptr[offset+1]; a = imagebufptr[offset]; *imagebuf = r << 24 | g << 16 | b << 8 | a; imagebuf++; } c->width = width; c->height = height; bitmap_modified(icon_c->bitmap); content_set_ready(c); content_set_done(c); content_set_status(c, ""); if(dobj) FreeDiskObject(dobj); if(format==IDFMT_PALETTEMAPPED) FreeVec(imagebufptr); return true; }
/** PNG content to bitmap conversion. * * This routine generates a bitmap object from a PNG image content */ static struct bitmap * png_cache_convert(struct content *c) { png_structp png_ptr; png_infop info_ptr; png_infop end_info_ptr; volatile struct bitmap *bitmap = NULL; struct png_cache_read_data_s png_cache_read_data; png_uint_32 width, height; volatile png_bytep *row_pointers = NULL; png_cache_read_data.data = content__get_source_data(c, &png_cache_read_data.size); if ((png_cache_read_data.data == NULL) || (png_cache_read_data.size <= 8)) { return NULL; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, nspng_error, nspng_warning); if (png_ptr == NULL) { return NULL; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, NULL, NULL); return NULL; } end_info_ptr = png_create_info_struct(png_ptr); if (end_info_ptr == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; } /* setup error exit path */ if (setjmp(png_jmpbuf(png_ptr))) { /* cleanup and bail */ goto png_cache_convert_error; } /* read from a buffer instead of stdio */ png_set_read_fn(png_ptr, &png_cache_read_data, png_cache_read_fn); /* ensure the png info structure is populated */ png_read_info(png_ptr, info_ptr); /* setup output transforms */ nspng_setup_transforms(png_ptr, info_ptr); width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); /* Claim the required memory for the converted PNG */ bitmap = bitmap_create(width, height, BITMAP_NEW); if (bitmap == NULL) { /* cleanup and bail */ goto png_cache_convert_error; } row_pointers = calc_row_pointers((struct bitmap *) bitmap); if (row_pointers != NULL) { png_read_image(png_ptr, (png_bytep *) row_pointers); } png_cache_convert_error: /* cleanup png read */ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr); free((png_bytep *) row_pointers); if (bitmap != NULL) bitmap_modified((struct bitmap *)bitmap); return (struct bitmap *)bitmap; }