Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pixmap Paint: Add Gamut integration #436

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
136 changes: 115 additions & 21 deletions pixmappaint.d
Original file line number Diff line number Diff line change
Expand Up @@ -135,26 +135,6 @@ struct Pixmap {
this.width = width;
}

static {
/++
Creates a Pixmap wrapping the pixel data from the provided `TrueColorImage`.

Interoperability function: `arsd.color`
+/
Pixmap fromTrueColorImage(TrueColorImage source) @nogc {
return Pixmap(source.imageData.colors, source.width);
}

/++
Creates a Pixmap wrapping the pixel data from the provided `MemoryImage`.

Interoperability function: `arsd.color`
+/
Pixmap fromMemoryImage(MemoryImage source) {
return fromTrueColorImage(source.getAsTrueColorImage());
}
}

@safe pure nothrow @nogc:

/// Height of the buffer, i.e. the number of lines
Expand Down Expand Up @@ -280,9 +260,123 @@ private struct OriginRectangle {
}
}

/++
Creates a Pixmap wrapping the pixel data of the provided `TrueColorImage`.

Interoperability function: `arsd.color`
+/
Pixmap toPixmap(TrueColorImage source) @nogc {
return Pixmap(source.imageData.colors, source.width);
}

/++
Creates a Pixmap wrapping the pixel data from the provided `MemoryImage`.

Interoperability function: `arsd.color`
+/
Pixmap toPixmap(MemoryImage source) {
return source.getAsTrueColorImage().toPixmap();
}

// ==== Gamut integration ====

/++
Reports whether the integration functionality for
the $(B Gamut) image decoding/encoding library by $(I AuburnSounds)
is available.

Compile-time setting that is automatically enabled
if importing `Image` from module `gamut` succeeds.

See_Also:
<https://github.com/AuburnSounds/gamut>
+/
enum bool hasGamutIntegration = __traits(compiles, () { import gamut : GamutImage = Image; });

//static if (hasGamutIntegration) {
// pragma(msg, "arsd.pixmappaint: Gamut integration enabled");
//}

/++
This means that something went wrong using the $(I Gamut) integration of Pixmap Paint.
+/
class GamutIntegrationException : ArsdExceptionBase {
this(string operation, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @trusted {
super(operation, file, line, next);
}
}

static if (hasGamutIntegration) {
import gamut : GamutImage = Image;

/++
Creates a Pixmap copying the pixel data from the provided [GamutImage].

---
// Load image using Gamut
import gamut;
Image img;
img.loadFromFile("dunes.jpg");

// Convert to Pixmap
Pixmap pixmap = img.toPixmap();
---
+/
bool toPixmap(ref GamutImage source, out Pixmap result) @trusted nothrow
in (source.isValid) {
import gamut;

enum supportedLayout = (LAYOUT_GAPLESS | LAYOUT_VERT_STRAIGHT);
enum supportedFormat = PixelType.rgba8;

immutable bool needsConversion = (
(source.layoutConstraints != supportedLayout)
|| (source.type != supportedFormat)
);

if (needsConversion) {
source = source.clone();

immutable conversionSuccessful = source.convertTo(supportedFormat, supportedLayout);
if (!conversionSuccessful) {
return false;
}
}

Pixel[] data = source.allPixelsAtOnce()
.castTo!(void[])
.castTo!(Pixel[])
.dup;

result = Pixmap(data, source.width);
return true;
}

/++
Creates a Pixmap copying the pixel data from the provided [GamutImage].
+/
Pixmap toPixmap(ref GamutImage source) @safe {
if (source.isError) {
import std.format : format;

throw new GamutIntegrationException(format!"Invalid source image. Gamut reports: \"%s\""(source.errorMessage));
}

Pixmap result;
const success = toPixmap(source, result);

if (!success) {
throw new GamutIntegrationException("Failed to convert `gamut`.`Image` to a supported format.");
}

return result;
}
}

@safe pure nothrow @nogc:

// misc
// ==== Misc functions ====

private {
Point pos(Rectangle r) => r.upperLeft;

Expand Down