Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/vips/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Breaking Changes

- Remove unused `batchResizeImage` and `vipsBatchResizeImage` exports. The concurrent sideload pipeline (introduced in [#75888](https://github.com/WordPress/gutenberg/pull/75888)) generates each sub-size through its own queued resize/upload operation, so the single-pass batch path no longer has any callers ([#77247](https://github.com/WordPress/gutenberg/issues/77247)).

## 1.5.0 (2026-04-29)

## 1.4.0 (2026-04-15)
Expand Down
38 changes: 0 additions & 38 deletions packages/vips/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,6 @@ npm install @wordpress/vips --save

<!-- START TOKEN(Autogenerated API docs) -->

### batchResizeImage

Resizes an image into multiple sizes in a single pass using copyMemory().

Decodes the source image once, materializes it in WASM memory via copyMemory(), then uses thumbnailImage() for each sub-size. This avoids re-decoding the source for every thumbnail.

_Parameters_

- _id_ `ItemId`: Item ID.
- _buffer_ `ArrayBuffer`: Original file buffer.
- _inputType_ `string`: Input mime type.
- _outputType_ `string`: Output mime type for all results.
- _resizes_ `BatchResizeConfig[]`: Array of resize configurations.
- _smartCrop_ Whether to use smart cropping (i.e. saliency-aware).

_Returns_

- `Promise< BatchResizeResult[] >`: Array of processed results, one per resize config.

### cancelOperations

Cancels all ongoing image operations for a given item ID.
Expand Down Expand Up @@ -122,25 +103,6 @@ _Returns_

- `Promise< { buffer: ArrayBuffer | ArrayBufferLike; width: number; height: number; } >`: Rotated file data plus the new dimensions.

### vipsBatchResizeImage

Resizes an image into multiple sizes in a single pass using copyMemory().

Decodes the source image once, materializes it in WASM memory via copyMemory(), then uses thumbnailImage() for each sub-size. This avoids re-decoding the source for every thumbnail.

_Parameters_

- _id_ `ItemId`: Item ID.
- _buffer_ `ArrayBuffer`: Original file buffer.
- _inputType_ `string`: Input mime type.
- _outputType_ `string`: Output mime type for all results.
- _resizes_ `BatchResizeConfig[]`: Array of resize configurations.
- _smartCrop_ Whether to use smart cropping (i.e. saliency-aware).

_Returns_

- `Promise< BatchResizeResult[] >`: Array of processed results, one per resize config.

### vipsCancelOperations

Cancels all ongoing image operations for a given item ID.
Expand Down
108 changes: 0 additions & 108 deletions packages/vips/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,113 +407,6 @@ export async function resizeImage(
}
}

/**
* Configuration for a single resize operation within a batch.
*/
interface BatchResizeConfig {
resize: ImageSizeCrop;
quality: number;
}

/**
* Result from a single resize operation within a batch.
*/
interface BatchResizeResult {
buffer: ArrayBuffer | ArrayBufferLike;
width: number;
height: number;
originalWidth: number;
originalHeight: number;
}

/**
* Resizes an image into multiple sizes in a single pass using copyMemory().
*
* Decodes the source image once, materializes it in WASM memory via
* copyMemory(), then uses thumbnailImage() for each sub-size. This avoids
* re-decoding the source for every thumbnail.
*
* @param id Item ID.
* @param buffer Original file buffer.
* @param inputType Input mime type.
* @param outputType Output mime type for all results.
* @param resizes Array of resize configurations.
* @param smartCrop Whether to use smart cropping (i.e. saliency-aware).
* @return Array of processed results, one per resize config.
*/
export async function batchResizeImage(
id: ItemId,
buffer: ArrayBuffer,
inputType: string,
outputType: string,
resizes: BatchResizeConfig[],
smartCrop = false
): Promise< BatchResizeResult[] > {
const ext = outputType.split( '/' )[ 1 ];

inProgressOperations.add( id );

try {
const vips = await getVips();

// Do not load animation frames for batch resize — copyMemory()
// would materialize all frames and use excessive memory.
const loadOptions: LoadOptions< typeof inputType > = {};

const sourceImage = vips.Image.newFromBuffer( buffer, '', loadOptions );

sourceImage.onProgress = () => {
if ( ! inProgressOperations.has( id ) ) {
sourceImage.kill = true;
}
};

const { width: originalWidth, pageHeight: originalHeight } =
sourceImage;

// Materialize the decoded image in WASM memory.
// This renders the full pipeline once so thumbnailImage() calls
// do not re-decode the source.
const memImage = sourceImage.copyMemory();

const results: BatchResizeResult[] = [];

for ( const config of resizes ) {
// Check cancellation between thumbnails.
if ( ! inProgressOperations.has( id ) ) {
break;
}

const image = applyResizeAndCrop(
config.resize,
originalWidth,
originalHeight,
smartCrop,
( resizeWidth, thumbnailOptions ) =>
memImage.thumbnailImage( resizeWidth, thumbnailOptions )
);

const saveOptions = buildSaveOptions( outputType, config.quality );
const outBuffer = image.writeToBuffer( `.${ ext }`, saveOptions );

results.push( {
buffer: outBuffer.buffer,
width: image.width,
height: image.pageHeight,
originalWidth,
originalHeight,
} );
}

// Only call after all images are no longer being used.
cleanup?.();

return results;
} finally {
inProgressOperations.delete( id );
}
}

/**
* Rotates an image based on EXIF orientation value.
*
Expand Down Expand Up @@ -643,7 +536,6 @@ export {
convertImageFormat as vipsConvertImageFormat,
compressImage as vipsCompressImage,
resizeImage as vipsResizeImage,
batchResizeImage as vipsBatchResizeImage,
rotateImage as vipsRotateImage,
hasTransparency as vipsHasTransparency,
cancelOperations as vipsCancelOperations,
Expand Down
44 changes: 0 additions & 44 deletions packages/vips/src/vips-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,50 +129,6 @@ export async function vipsResizeImage(
return api.resizeImage( id, buffer, type, resize, smartCrop, quality );
}

/**
* Resizes an image into multiple sizes in a single pass using a worker.
*
* Decodes the source once and uses copyMemory() + thumbnailImage()
* to avoid re-decoding for each sub-size.
*
* @param id Item ID.
* @param buffer Original file buffer.
* @param inputType Input mime type.
* @param outputType Output mime type for all results.
* @param resizes Array of resize configurations.
* @param smartCrop Whether to use smart cropping.
* @return Array of processed results.
*/
export async function vipsBatchResizeImage(
id: ItemId,
buffer: ArrayBuffer,
inputType: string,
outputType: string,
resizes: Array< {
resize: ImageSizeCrop;
quality: number;
} >,
smartCrop = false
): Promise<
Array< {
buffer: ArrayBuffer | ArrayBufferLike;
width: number;
height: number;
originalWidth: number;
originalHeight: number;
} >
> {
const api = getWorkerAPI();
return api.batchResizeImage(
id,
buffer,
inputType,
outputType,
resizes,
smartCrop
);
}

/**
* Determines whether an image has an alpha channel using vips in a worker.
*
Expand Down
2 changes: 0 additions & 2 deletions packages/vips/src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
convertImageFormat,
compressImage,
resizeImage,
batchResizeImage,
rotateImage,
hasTransparency,
} from './index';
Expand All @@ -32,7 +31,6 @@ const api = {
convertImageFormat,
compressImage,
resizeImage,
batchResizeImage,
rotateImage,
hasTransparency,
};
Expand Down
Loading