Repository: godotengine/godot
File: core/io/image.cpp (C++)

Code before:
	return (data.size() == 0);
}

Vector<uint8_t> Image::get_data() const {
	return data;
}

void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
	ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels.");
	ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels.");
	ERR_FAIL_COND_MSG(p_width > MAX_WIDTH,
			"The Image width specified (" + itos(p_width) + " pixels) cannot be greater than " + itos(MAX_WIDTH) + "pixels.");
	ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT,
			"The Image height specified (" + itos(p_height) + " pixels) cannot be greater than " + itos(MAX_HEIGHT) + "pixels.");
	ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS,
			"Too many pixels for Image. Maximum is " + itos(MAX_WIDTH) + "x" + itos(MAX_HEIGHT) + " = " + itos(MAX_PIXELS) + "pixels.");
	ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "The Image format specified (" + itos(p_format) + ") is out of range. See Image's Format enum.");

	int mm = 0;
	int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
	data.resize(size);

	{
		uint8_t *w = data.ptrw();
		memset(w, 0, size);
	}

	width = p_width;
	height = p_height;
	mipmaps = p_use_mipmaps;
	format = p_format;
}

void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
	ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels.");
	ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels.");
	ERR_FAIL_COND_MSG(p_width > MAX_WIDTH,
			"The Image width specified (" + itos(p_width) + " pixels) cannot be greater than " + itos(MAX_WIDTH) + " pixels.");
	ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT,
			"The Image height specified (" + itos(p_height) + " pixels) cannot be greater than " + itos(MAX_HEIGHT) + " pixels.");
	ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS,
			"Too many pixels for Image. Maximum is " + itos(MAX_WIDTH) + "x" + itos(MAX_HEIGHT) + " = " + itos(MAX_PIXELS) + "pixels .");
	ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "The Image format specified (" + itos(p_format) + ") is out of range. See Image's Format enum.");

	int mm;
	int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);

	if (unlikely(p_data.size() != size)) {
		String description_mipmaps;
		if (p_use_mipmaps) {
			const int num_mipmaps = get_image_required_mipmaps(p_width, p_height, p_format);

Review comment (refactor):
I think this warrants further refactoring, it's weird to have static `create_empty` and `create_from_data` and non-static `create` with two variants.

Maybe:
- Move `create(int p_width, int p_height, bool p_use_mipmaps, Format p_format)` logic to `create_empty` (and rename to `create` to match bindings)
  * Or keep the `create_empty` name and use that for the bindings too. We should strive to have consistent between core C++ API and bindings for GDExtension's sake.
- Move `create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data)` logic to `set_data` and use it in `create_from_data`.

Code after:

Vector<uint8_t> Image::get_data() const {
	return data;
}

Ref<Image> Image::create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
	Ref<Image> image;
	image.instantiate();
	image->initialize_data(p_width, p_height, p_use_mipmaps, p_format);
	return image;
}

Ref<Image> Image::create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
	Ref<Image> image;
	image.instantiate();
	image->initialize_data(p_width, p_height, p_use_mipmaps, p_format, p_data);
	return image;
}

void Image::set_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
	initialize_data(p_width, p_height, p_use_mipmaps, p_format, p_data);
}

void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
	ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels.");
	ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels.");
	ERR_FAIL_COND_MSG(p_width > MAX_WIDTH,
			"The Image width specified (" + itos(p_width) + " pixels) cannot be greater than " + itos(MAX_WIDTH) + "pixels.");
	ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT,
			"The Image height specified (" + itos(p_height) + " pixels) cannot be greater than " + itos(MAX_HEIGHT) + "pixels.");
	ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS,
			"Too many pixels for Image. Maximum is " + itos(MAX_WIDTH) + "x" + itos(MAX_HEIGHT) + " = " + itos(MAX_PIXELS) + "pixels.");
	ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "The Image format specified (" + itos(p_format) + ") is out of range. See Image's Format enum.");

	int mm = 0;
	int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
	data.resize(size);

	{
		uint8_t *w = data.ptrw();
		memset(w, 0, size);
	}

	width = p_width;
	height = p_height;
	mipmaps = p_use_mipmaps;
	format = p_format;
}

void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
	ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels.");