diff --git a/docs/image_formats_support.md b/docs/image_formats_support.md index 9b474929..03037191 100644 --- a/docs/image_formats_support.md +++ b/docs/image_formats_support.md @@ -9,6 +9,7 @@ At the moment, imgproxy supports only the most popular image formats: * ICO; * SVG _(source only)_; * HEIC; +* BMP; * TIFF. ## GIF support @@ -25,6 +26,10 @@ imgproxy supports HEIC only when using libvips 8.8.0+. Official imgproxy Docker By default, imgproxy saves HEIC images as JPEG. You need to explicitly specify the `format` option to get HEIC output. +## BMP support + +By default, imgproxy saves BMP images as JPEG. You need to explicitly specify the `format` option to get BMP output. + ## Animated images support Since processing of animated images is pretty heavy, only one frame is processed by default. You can increase the maximum of animation frames to process with the following variable: diff --git a/image_type.go b/image_type.go index 17ab22bf..0dd2fde2 100644 --- a/image_type.go +++ b/image_type.go @@ -24,6 +24,7 @@ const ( imageTypeICO = imageType(C.ICO) imageTypeSVG = imageType(C.SVG) imageTypeHEIC = imageType(C.HEIC) + imageTypeBMP = imageType(C.BMP) imageTypeTIFF = imageType(C.TIFF) contentDispositionFilenameFallback = "image" @@ -39,6 +40,7 @@ var ( "ico": imageTypeICO, "svg": imageTypeSVG, "heic": imageTypeHEIC, + "bmp": imageTypeBMP, "tiff": imageTypeTIFF, } @@ -49,6 +51,7 @@ var ( imageTypeGIF: "image/gif", imageTypeICO: "image/x-icon", imageTypeHEIC: "image/heif", + imageTypeBMP: "image/bmp", imageTypeTIFF: "image/tiff", } @@ -59,6 +62,7 @@ var ( imageTypeGIF: "inline; filename=\"%s.gif\"", imageTypeICO: "inline; filename=\"%s.ico\"", imageTypeHEIC: "inline; filename=\"%s.heic\"", + imageTypeBMP: "inline; filename=\"%s.bmp\"", imageTypeTIFF: "inline; filename=\"%s.tiff\"", } ) diff --git a/vips.c b/vips.c index f090987c..63570bd9 100644 --- a/vips.c +++ b/vips.c @@ -84,6 +84,8 @@ vips_type_find_load_go(int imgtype) { return vips_type_find("VipsOperation", "magickload_buffer"); case (HEIC): return vips_type_find("VipsOperation", "heifload_buffer"); + case (BMP): + return vips_type_find("VipsOperation", "magickload_buffer"); case (TIFF): return vips_type_find("VipsOperation", "tiffload_buffer"); } @@ -106,6 +108,8 @@ vips_type_find_save_go(int imgtype) { return vips_type_find("VipsOperation", "magicksave_buffer"); case (HEIC): return vips_type_find("VipsOperation", "heifsave_buffer"); + case (BMP): + return vips_type_find("VipsOperation", "bmpsave_buffer"); case (TIFF): return vips_type_find("VipsOperation", "tiffsave_buffer"); } @@ -183,6 +187,16 @@ vips_heifload_go(void *buf, size_t len, VipsImage **out) { #endif } +int +vips_bmpload_go(void *buf, size_t len, VipsImage **out) { +#if VIPS_SUPPORT_MAGICK + return vips_magickload_buffer(buf, len, out, NULL); +#else + vips_error("vips_bmpload_go", "Loading BMP is not supported"); + return 1; +#endif +} + int vips_tiffload_go(void *buf, size_t len, VipsImage **out) { #if VIPS_SUPPORT_TIFF @@ -529,6 +543,16 @@ vips_tiffsave_go(VipsImage *in, void **buf, size_t *len, int quality) { #endif } +int +vips_bmpsave_go(VipsImage *in, void **buf, size_t *len, int quality) { +#if VIPS_SUPPORT_MAGICK + return vips_magicksave_buffer(in, buf, len, "format", "bmp", "quality", quality, NULL); +#else + vips_error("vips_bmpsave_go", "Saving BMP is not supported"); + return 1; +#endif +} + void vips_cleanup() { vips_error_clear(); diff --git a/vips.go b/vips.go index af4a5071..919c6d6c 100644 --- a/vips.go +++ b/vips.go @@ -97,6 +97,9 @@ func initVips() { if int(C.vips_type_find_load_go(C.int(imageTypeHEIC))) != 0 { vipsTypeSupportLoad[imageTypeHEIC] = true } + if int(C.vips_type_find_load_go(C.int(imageTypeBMP))) != 0 { + vipsTypeSupportLoad[imageTypeBMP] = true + } if int(C.vips_type_find_load_go(C.int(imageTypeTIFF))) != 0 { vipsTypeSupportLoad[imageTypeTIFF] = true } @@ -119,6 +122,9 @@ func initVips() { if int(C.vips_type_find_save_go(C.int(imageTypeHEIC))) != 0 { vipsTypeSupportSave[imageTypeHEIC] = true } + if int(C.vips_type_find_save_go(C.int(imageTypeBMP))) != 0 { + vipsTypeSupportSave[imageTypeBMP] = true + } if int(C.vips_type_find_save_go(C.int(imageTypeTIFF))) != 0 { vipsTypeSupportSave[imageTypeTIFF] = true } @@ -208,6 +214,8 @@ func (img *vipsImage) Load(data []byte, imgtype imageType, shrink int, scale flo err = C.vips_icoload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.int(bestPage), &tmp) case imageTypeHEIC: err = C.vips_heifload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &tmp) + case imageTypeBMP: + err = C.vips_bmpload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &tmp) case imageTypeTIFF: err = C.vips_tiffload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &tmp) } @@ -244,6 +252,8 @@ func (img *vipsImage) Save(imgtype imageType, quality int) ([]byte, context.Canc err = C.vips_icosave_go(img.VipsImage, &ptr, &imgsize) case imageTypeHEIC: err = C.vips_heifsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality)) + case imageTypeBMP: + err = C.vips_bmpsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality)) case imageTypeTIFF: err = C.vips_tiffsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality)) } diff --git a/vips.h b/vips.h index 6a981ac5..f36fa65b 100644 --- a/vips.h +++ b/vips.h @@ -13,6 +13,7 @@ enum ImgproxyImageTypes { ICO, SVG, HEIC, + BMP, TIFF }; @@ -33,6 +34,7 @@ int vips_gifload_go(void *buf, size_t len, int pages, VipsImage **out); int vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out); int vips_icoload_go(void *buf, size_t len, int page, VipsImage **out); int vips_heifload_go(void *buf, size_t len, VipsImage **out); +int vips_bmpload_go(void *buf, size_t len, VipsImage **out); int vips_tiffload_go(void *buf, size_t len, VipsImage **out); int vips_get_orientation(VipsImage *image); @@ -86,6 +88,7 @@ int vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality); int vips_gifsave_go(VipsImage *in, void **buf, size_t *len); int vips_icosave_go(VipsImage *in, void **buf, size_t *len); int vips_heifsave_go(VipsImage *in, void **buf, size_t *len, int quality); +int vips_bmpsave_go(VipsImage *in, void **buf, size_t *len, int quality); int vips_tiffsave_go(VipsImage *in, void **buf, size_t *len, int quality); void vips_cleanup();