void Image_save(Image *self) { //Image_flipY(self); if (strcmp(self->fileType, "png")==0) { PNGImage *image = PNGImage_new(); PNGImage_setExternalUArray_(image, self->byteArray); PNGImage_path_(image, self->path); PNGImage_width_(image, self->width); PNGImage_height_(image, self->height); PNGImage_components_(image, Image_componentCount(self)); PNGImage_save(image); Image_error_(self, PNGImage_error(image)); PNGImage_free(image); } else if (strcmp(self->fileType, "jpg")==0) { JPGImage *image = JPGImage_new(); JPGImage_setExternalUArray_(image, self->byteArray); JPGImage_path_(image, self->path); JPGImage_quality_(image, self->encodingQuality); JPGImage_width_(image, self->width); JPGImage_height_(image, self->height); if (Image_isRGBA8(self)) { Image_removeAlpha(self); } if (!Image_isRGB8(self)) { Image_error_(self, "can only save RGB images to JPEG"); return; } JPGImage_components_(image, Image_componentCount(self)); JPGImage_save(image); Image_error_(self, JPGImage_error(image)); JPGImage_free(image); } else if (strcmp(self->fileType, "tiff")==0 || strcmp(self->fileType, "tif")==0) { TIFFImage *image = TIFFImage_new(); TIFFImage_setExternalUArray_(image, self->byteArray); TIFFImage_path_(image, self->path); TIFFImage_width_(image, self->width); TIFFImage_height_(image, self->height); TIFFImage_components_(image, Image_componentCount(self)); TIFFImage_save(image); Image_error_(self, TIFFImage_error(image)); TIFFImage_free(image); } else { Image_error_(self, "unknown file type"); } //Image_flipY(self); }
IoObject *IoImage_isLA8(IoImage *self, IoObject *locals, IoMessage *m) { /*doc Image isLA8 Returns true if the receiver is in LA8 (8bit Luminance-Alpha) format, false otherwise. */ return IOBOOL(self, Image_componentCount(DATA(self)->image) == 2); }
IoObject *IoImage_componentCount(IoImage *self, IoObject *locals, IoMessage *m) { /*doc Image componentCount Returns the number of color components in the receiver as a Number. */ return IONUMBER(Image_componentCount(DATA(self)->image)); }
IOIMAGE_API IoObject *IoImage_componentPlain(IoImage *self, IoObject *locals, IoMessage *m) { /*doc Image componentPlain(component) Removes other components except specified from the image. Returns self. */ int component = IoMessage_locals_intArgAt_(m, locals, 0) % Image_componentCount(DATA(self)->image); Image_bitMask(DATA(self)->image, component, 255); return self; }
inline unsigned char *Image_pixelAt(Image *self, int x, int y) { int bps = 8; int spp = Image_componentCount(self); int w = self->width; int h = self->height; uint8_t *p = (uint8_t *)UArray_bytes(self->byteArray); if (x < 0) { x = 0; } else if (x > w - 1) { x = w - 1; } if (y < 0) { y = 0; } else if (y > h - 1) { y = h - 1; } return p + (((x + (y * w)) * (spp * bps)) / 8); }
IOIMAGE_API IoObject *IoImage_bitPlain(IoImage *self, IoObject *locals, IoMessage *m) { /*doc Image bitPlain(component, bit) Replaces contents with black-and-white image where white appears if and only if specified component contained 1 on the specified bit plain. Returns self. */ int component = IoMessage_locals_intArgAt_(m, locals, 0) % Image_componentCount(DATA(self)->image); int bit = IoMessage_locals_intArgAt_(m, locals, 0) % 8; Image_bitMask(DATA(self)->image, component, 1 << bit); UArray* imageByteArray = Image_byteArray(DATA(self)->image); UArray_multiplyScalarDouble_(imageByteArray, (1 << (7 - bit))); return self; }
void Image_crop(Image *self, int cx, int cy, int w, int h) { int pixelSize = Image_componentCount(self); int x, y; if (cx > self->width) { Image_error_(self, "crop x > width"); return; } if (cy > self->height) { Image_error_(self, "crop y > height"); return; } if (cx+w > self->width) { w = self->width - cx; } if (cy+h > self->height) { h = self->height - cy; } for (x = 0; x < w; x ++) { for (y = 0; y < h; y ++) { unsigned char *ip = Image_pixelAt(self, cx+x, cy+y); unsigned char *op = Image_pixelAt(self, x, y); memcpy(op, ip, pixelSize); } } UArray_setSize_(self->byteArray, w*h*pixelSize); self->width = w; self->height = h; }