bool bitmap_resize(struct bitmap *img, HermesHandle hermes_h, HermesFormat *fmt, int nw, int nh) { unsigned int state = 0; short bpp = bitmap_get_bpp( img ); int stride = bitmap_get_rowstride( img ); int err; if( img->resized != NULL ) { if( img->resized->width != nw || img->resized->height != nh ) { bitmap_destroy( img->resized ); img->resized = NULL; } else { /* the bitmap is already resized */ return(true); } } /* allocate the mem for resized bitmap */ if (img->opaque == true) { state |= BITMAP_OPAQUE; } img->resized = bitmap_create_ex( nw, nh, bpp, nw*bpp, state, NULL ); if( img->resized == NULL ) { printf("W: %d, H: %d, bpp: %d\n", nw, nh, bpp); assert(img->resized); return(false); } /* allocate an converter, only for resizing */ err = Hermes_ConverterRequest( hermes_h, fmt, fmt ); if( err == 0 ) { return(false); } err = Hermes_ConverterCopy( hermes_h, img->pixdata, 0, /* x src coord of top left in pixel coords */ 0, /* y src coord of top left in pixel coords */ bitmap_get_width( img ), bitmap_get_height( img ), stride, /* stride as bytes */ img->resized->pixdata, 0, /* x dst coord of top left in pixel coords */ 0, /* y dst coord of top left in pixel coords */ nw, nh, bitmap_get_rowstride(img->resized) /* stride as bytes */ ); if( err == 0 ) { bitmap_destroy( img->resized ); img->resized = NULL; return(false); } return(true); }
/** calculate an array of row pointers into a bitmap data area */ static png_bytep *calc_row_pointers(struct bitmap *bitmap) { int height = bitmap_get_height(bitmap); unsigned char *buffer= bitmap_get_buffer(bitmap); size_t rowstride = bitmap_get_rowstride(bitmap); png_bytep *row_ptrs; int hloop; row_ptrs = malloc(sizeof(png_bytep) * height); if (row_ptrs != NULL) { for (hloop = 0; hloop < height; hloop++) { row_ptrs[hloop] = buffer + (rowstride * hloop); } } return row_ptrs; }
static struct bitmap *amiga_dt_picture_cache_convert(struct content *c) { LOG(("amiga_dt_picture_cache_convert")); union content_msg_data msg_data; const uint8 *data; UBYTE *bm_buffer; ULONG size; Object *dto; struct bitmap *bitmap; unsigned int bm_flags = BITMAP_NEW; int bm_format = PBPAFMT_RGBA; /* This is only relevant for picture datatypes... */ data = (uint8 *)content__get_source_data(c, &size); if(dto = NewDTObject(NULL, DTA_SourceType, DTST_MEMORY, DTA_SourceAddress, data, DTA_SourceSize, size, DTA_GroupID, GID_PICTURE, PDTA_DestMode, PMODE_V43, TAG_DONE)) { bitmap = bitmap_create(c->width, c->height, bm_flags); if (!bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return NULL; } bm_buffer = bitmap_get_buffer(bitmap); IDoMethod(dto, PDTM_READPIXELARRAY, bm_buffer, bm_format, bitmap_get_rowstride(bitmap), 0, 0, c->width, c->height); DisposeDTObject(dto); } else return NULL; return bitmap; }
static struct bitmap *amiga_dt_picture_cache_convert(struct content *c) { LOG(("amiga_dt_picture_cache_convert")); union content_msg_data msg_data; UBYTE *bm_buffer; Object *dto; struct bitmap *bitmap; unsigned int bm_flags = BITMAP_NEW; #ifdef __amigaos4__ int bm_format = PBPAFMT_RGBA; #else int bm_format = PBPAFMT_ARGB; #endif struct amiga_dt_picture_content *adt = (struct amiga_dt_picture_content *)c; if(dto = amiga_dt_picture_newdtobject(adt)) { bitmap = bitmap_create(c->width, c->height, bm_flags); if (!bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return NULL; } bm_buffer = bitmap_get_buffer(bitmap); IDoMethod(dto, PDTM_READPIXELARRAY, bm_buffer, bm_format, bitmap_get_rowstride(bitmap), 0, 0, c->width, c->height); #ifndef __amigaos4__ ami_bitmap_argb_to_rgba(bitmap); #endif bitmap_set_opaque(bitmap, bitmap_test_opaque(bitmap)); DisposeDTObject(dto); adt->dto = NULL; } else return NULL; return bitmap; }
void bitmap_to_mfdb(void * bitmap, MFDB * out) { struct bitmap * bm; uint8_t * tmp; size_t dststride, oldstride; bm = bitmap; assert( out != NULL ); assert( bm->pixdata != NULL ); oldstride = bitmap_get_rowstride( bm ); dststride = MFDB_STRIDE( bm->width ); if( oldstride != dststride * bm->bpp ) { assert( oldstride <= dststride ); /* we need to convert the img to new rowstride */ tmp = bm->pixdata; bm->pixdata = calloc(1, dststride * bm->bpp * bm->height ); if( tmp == NULL ){ bm->pixdata = tmp; out->fd_addr = NULL; return; } bm->rowstride = dststride * bm->bpp; int i=0; for( i=0; i<bm->height; i++) { memcpy( (bm->pixdata+i*bm->rowstride), (tmp + i*oldstride), oldstride); } free( tmp ); } out->fd_w = dststride; out->fd_h = bm->height; out->fd_wdwidth = dststride >> 4; out->fd_addr = bm->pixdata; out->fd_stand = 0; out->fd_nplanes = (short)bm->bpp; out->fd_r1 = out->fd_r2 = out->fd_r3 = 0; }
/** * info_callback -- PNG header has been completely received, prepare to process * image data */ static void info_callback(png_structp png_s, png_infop info) { int interlace; png_uint_32 width, height; nspng_content *png_c = png_get_progressive_ptr(png_s); width = png_get_image_width(png_s, info); height = png_get_image_height(png_s, info); interlace = png_get_interlace_type(png_s, info); png_c->base.width = width; png_c->base.height = height; png_c->base.size += width * height * 4; /* see if progressive-conversion should continue */ if (image_cache_speculate((struct content *)png_c) == false) { longjmp(png_jmpbuf(png_s), CBERR_NOPRE); } /* Claim the required memory for the converted PNG */ png_c->bitmap = bitmap_create(width, height, BITMAP_NEW); if (png_c->bitmap == NULL) { /* Failed to create bitmap skip pre-conversion */ longjmp(png_jmpbuf(png_s), CBERR_NOPRE); } png_c->rowstride = bitmap_get_rowstride(png_c->bitmap); png_c->bpp = bitmap_get_bpp(png_c->bitmap); nspng_setup_transforms(png_s, info); png_c->rowbytes = png_get_rowbytes(png_s, info); png_c->interlace = (interlace == PNG_INTERLACE_ADAM7); LOG(("size %li * %li, rowbytes %zu", (unsigned long)width, (unsigned long)height, png_c->rowbytes)); }
HPDF_Image pdf_extract_image(struct bitmap *bitmap) { HPDF_Image image = NULL; hlcache_handle *content = NULL; /* TODO - get content from bitmap pointer */ if (content) { const char *source_data; unsigned long source_size; /*Not sure if I don't have to check if downloading has been finished. Other way - lock pdf plotting while fetching a website */ source_data = content_get_source_data(content, &source_size); switch(content_get_type(content)){ /*Handle "embeddable" types of images*/ case CONTENT_JPEG: image = HPDF_LoadJpegImageFromMem(pdf_doc, (const HPDF_BYTE *) source_data, source_size); break; /*Disabled until HARU PNG support will be more stable. case CONTENT_PNG: image = HPDF_LoadPngImageFromMem(pdf_doc, (const HPDF_BYTE *)content->source_data, content->total_size); break;*/ default: break; } } if (!image) { HPDF_Image smask; unsigned char *img_buffer, *rgb_buffer, *alpha_buffer; int img_width, img_height, img_rowstride; int i, j; /*Handle pixmaps*/ img_buffer = bitmap_get_buffer(bitmap); img_width = bitmap_get_width(bitmap); img_height = bitmap_get_height(bitmap); img_rowstride = bitmap_get_rowstride(bitmap); rgb_buffer = (unsigned char *)malloc(3 * img_width * img_height); alpha_buffer = (unsigned char *)malloc(img_width * img_height); if (rgb_buffer == NULL || alpha_buffer == NULL) { NSLOG(netsurf, INFO, "Not enough memory to create RGB buffer"); free(rgb_buffer); free(alpha_buffer); return NULL; } for (i = 0; i < img_height; i++) for (j = 0; j < img_width; j++) { rgb_buffer[((i * img_width) + j) * 3] = img_buffer[(i * img_rowstride) + (j * 4)]; rgb_buffer[(((i * img_width) + j) * 3) + 1] = img_buffer[(i * img_rowstride) + (j * 4) + 1]; rgb_buffer[(((i * img_width) + j) * 3) + 2] = img_buffer[(i * img_rowstride) + (j * 4) + 2]; alpha_buffer[(i * img_width)+j] = img_buffer[(i * img_rowstride) + (j * 4) + 3]; } smask = HPDF_LoadRawImageFromMem(pdf_doc, alpha_buffer, img_width, img_height, HPDF_CS_DEVICE_GRAY, 8); image = HPDF_LoadRawImageFromMem(pdf_doc, rgb_buffer, img_width, img_height, HPDF_CS_DEVICE_RGB, 8); if (HPDF_Image_AddSMask(image, smask) != HPDF_OK) image = NULL; free(rgb_buffer); free(alpha_buffer); } return image; }
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; }