static void row_callback(png_structp png_s, png_bytep new_row, png_uint_32 row_num, int pass) { nspng_content *png_c = png_get_progressive_ptr(png_s); unsigned long rowbytes = png_c->rowbytes; unsigned char *buffer, *row; /* Give up if there's no bitmap */ if (png_c->bitmap == NULL) return; /* Abort if we've not got any data */ if (new_row == NULL) return; /* Get bitmap buffer */ buffer = bitmap_get_buffer(png_c->bitmap); if (buffer == NULL) { /* No buffer, bail out */ longjmp(png_jmpbuf(png_s), 1); } /* Calculate address of row start */ row = buffer + (png_c->rowstride * row_num); /* Handle interlaced sprites using the Adam7 algorithm */ if (png_c->interlace) { unsigned long dst_off; unsigned long src_off = 0; unsigned int start, step; start = interlace_start[pass]; step = interlace_step[pass]; row_num = interlace_row_start[pass] + interlace_row_step[pass] * row_num; /* Copy the data to our current row taking interlacing * into consideration */ row = buffer + (png_c->rowstride * row_num); for (dst_off = start; dst_off < rowbytes; dst_off += step) { row[dst_off++] = new_row[src_off++]; row[dst_off++] = new_row[src_off++]; row[dst_off++] = new_row[src_off++]; row[dst_off++] = new_row[src_off++]; } } else { /* Do a fast memcpy of the row data */ memcpy(row, new_row, rowbytes); } }
/** 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; }
bool ro_save_draw_bitmap(int x, int y, int width, int height, struct bitmap *bitmap, colour bg, bitmap_flags_t flags) { pencil_code code; const uint8_t *buffer; buffer = bitmap_get_buffer(bitmap); if (!buffer) { warn_user("NoMemory", 0); return false; } code = pencil_sprite(ro_save_draw_diagram, x * 2, (-y - height) * 2, width * 2, height * 2, ((char *) bitmap->sprite_area) + bitmap->sprite_area->first); if (code != pencil_OK) return ro_save_draw_error(code); return true; }
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; }
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; }