Skip to content

Commit

Permalink
docs: Convert more examples within the imagebufalgo chapter.
Browse files Browse the repository at this point in the history
Convert C++ and Python examples from the "Image transformations
and data movement" section of the "imagebufalgo" chapter into
tests within the "docs-examples" testsuites (AcademySoftwareFoundation#3992).

Update 'oiiotool' tabs to use a simple 'tab' instead of 'code-tab'
to prevent synchronized tab selection, which is inconsistent with the
other tabs using the 'literalinclude' directive.

Note: image hashes comparison can not be used for testing 'rotate',
'resample', 'resize', 'fit', and 'warp', as it produces minor differences
linked on the testing environment.

Signed-off-by: Jeremy Retailleau <jeremy.retailleau@gmail.com>
  • Loading branch information
buddly27 authored and lgritz committed Aug 25, 2024
1 parent 40e3056 commit b0cb53d
Show file tree
Hide file tree
Showing 8 changed files with 810 additions and 330 deletions.
616 changes: 310 additions & 306 deletions src/doc/imagebufalgo.rst

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion testsuite/docs-examples-cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ set (CMAKE_CXX_EXTENSIONS OFF)

# Make sure we have dependencies we need
find_package (OpenImageIO CONFIG REQUIRED)
find_package (Imath CONFIG REQUIRED)

# Special for OIIO testsuite when running in sanitize mode
if (DEFINED ENV{SANITIZE})
Expand All @@ -34,5 +35,5 @@ set (chapters imageioapi imageoutput imageinput writingplugins
foreach (chapter ${chapters})
add_executable(docs-examples-${chapter} src/docs-examples-${chapter}.cpp)
target_link_libraries (docs-examples-${chapter}
PRIVATE OpenImageIO::OpenImageIO)
PRIVATE OpenImageIO::OpenImageIO Imath::Imath)
endforeach ()
32 changes: 32 additions & 0 deletions testsuite/docs-examples-cpp/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,38 @@ text1.exr : 640 x 480, 3 channel, float openexr
SHA-1: 014ECFC5EBF07F77DF24A592F43BC7CB101534AE
text2.exr : 640 x 480, 3 channel, float openexr
SHA-1: 53359E96A286F909A89ACC99A67A9ED3BADC4A7A
channels-rgba.exr : 256 x 256, 4 channel, half openexr
SHA-1: C823E3701152B4B3C20DD79EA8A20CF4293F4B71
channels-rgb.exr : 256 x 256, 3 channel, half openexr
SHA-1: 4074B050432CE7C664CEC4546A46E74F9A310CDC
channels-brga.exr : 256 x 256, 4 channel, half openexr
SHA-1: 04E09E64C61CEA1634D26FB2E6C733875D163671
channels-alpha.exr : 256 x 256, 1 channel, half openexr
SHA-1: 99C332E70F321F0EA47C0F70AF8B0E3E6524F91F
channel-append.exr : 640 x 480, 5 channel, float openexr
SHA-1: F7ECA3179B1ABD2C45141DCEF0C17ECFE7E5A91F
copy.exr : 256 x 256, 4 channel, float openexr
SHA-1: 7044589C8B904DAF6A2BA3246224E97DD460AC93
crop.exr : 200 x 100, 4 channel, half openexr
SHA-1: 4DA3918566D087A9D2D9E93B2A7BABE971FE6BBD
cut.exr : 200 x 100, 4 channel, half openexr
SHA-1: 4DA3918566D087A9D2D9E93B2A7BABE971FE6BBD
paste.exr : 256 x 256, 4 channel, half openexr
SHA-1: 67A4C36DEAED98A5A8ABA5F0E0EDE697345DC22A
rotate-90.exr : 256 x 256, 4 channel, half openexr
SHA-1: AFFAEA876E8E7760226B017B0A89A3549B7A5895
rotate-180.exr : 256 x 256, 4 channel, half openexr
SHA-1: A5E42C5F18177DA146EC7E4567E4AE3AE2816C3C
rotate-270.exr : 256 x 256, 4 channel, half openexr
SHA-1: 46C803894186457376A0C590768C9DB4877737BB
flip.exr : 256 x 256, 4 channel, half openexr
SHA-1: A9EB9A8762BCD8DD161C00B01E2DF39E5C91B0D4
flop.exr : 256 x 256, 4 channel, half openexr
SHA-1: 7C10717DB4F2E21F0B4F6D5404C660CA8B504F5E
transpose.exr : 256 x 256, 4 channel, float openexr
SHA-1: 2E0E9151C138EA26A331AA4C1FB39DA70815D4F7
reorient.exr : 256 x 256, 4 channel, half openexr
SHA-1: 46C803894186457376A0C590768C9DB4877737BB
cshift.exr : 256 x 256, 4 channel, half openexr
SHA-1: 000F95FDC44D4DBDA8B4041C2506149C7AE28ACA
texture.exr : 256 x 256, 3 channel, half openexr (+mipmap)
Expand Down
16 changes: 16 additions & 0 deletions testsuite/docs-examples-cpp/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@
"box.exr",
"text1.exr",
"text2.exr",
"channels-rgba.exr",
"channels-rgb.exr",
"channels-brga.exr",
"channels-alpha.exr",
"channel-append.exr",
"copy.exr",
"crop.exr",
"cut.exr",
"paste.exr",
"rotate-90.exr",
"rotate-180.exr",
"rotate-270.exr",
"flip.exr",
"flop.exr",
"transpose.exr",
"reorient.exr",
"cshift.exr",
"texture.exr"
]
Expand Down
229 changes: 215 additions & 14 deletions testsuite/docs-examples-cpp/src/docs-examples-imagebufalgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
// https://github.com/AcademySoftwareFoundation/OpenImageIO


// TRICK: skip deprecated functions in IBA
#define DOXYGEN_SHOULD_SKIP_THIS

#include <Imath/ImathMatrix.h>



///////////////////////////////////////////////////////////////////////////
// This file contains code examples from the ImageBufAlgo chapter of the
// main OpenImageIO documentation.
Expand All @@ -16,6 +23,7 @@
#include <OpenImageIO/imagebufalgo.h>
using namespace OIIO;


void example1()
{
//
Expand Down Expand Up @@ -98,11 +106,12 @@ void example_fill()
// Create a new 640x480 RGB image, with a top-to-bottom gradient
// from red to pink
float pink[3] = { 1, 0.7, 0.7 };
float red[3] = { 1, 0, 0 };
ImageBuf A = ImageBufAlgo::fill (red, pink, ROI(0, 640, 0, 480, 0, 1, 0, 3));
float red[3] = { 1, 0, 0 };
ImageBuf A = ImageBufAlgo::fill(red, cspan<float>(pink),
ROI(0, 640, 0, 480, 0, 1, 0, 3));

// Draw a filled red rectangle overtop existing image A.
ImageBufAlgo::fill (A, red, ROI(50, 100, 75, 175));
ImageBufAlgo::fill (A, cspan<float>(red), ROI(50, 100, 75, 175));
// END-imagebufalgo-fill

A.write("fill.exr");
Expand All @@ -113,10 +122,11 @@ void example_checker()
// BEGIN-imagebufalgo-checker
// Create a new 640x480 RGB image, fill it with a two-toned gray
// checkerboard, the checkers being 64x64 pixels each.
ImageBuf A (ImageSpec(640, 480, 3, TypeDesc::FLOAT));
float dark[3] = { 0.1, 0.1, 0.1 };
ImageBuf A(ImageSpec(640, 480, 3, TypeDesc::FLOAT));
float dark[3] = { 0.1, 0.1, 0.1 };
float light[3] = { 0.4, 0.4, 0.4 };
ImageBufAlgo::checker (A, 64, 64, 1, dark, light, 0, 0, 0);
ImageBufAlgo::checker(A, 64, 64, 1, cspan<float>(dark), cspan<float>(light),
0, 0, 0);
// END-imagebufalgo-checker

A.write("checker.exr");
Expand Down Expand Up @@ -201,14 +211,14 @@ void example_text1()
ImageBuf ImgB = ImageBufAlgo::zero(ROI(0, 640, 0, 480, 0, 1, 0, 3));

// BEGIN-imagebufalgo-text1
ImageBufAlgo::render_text (ImgA, 50, 100, "Hello, world");
ImageBufAlgo::render_text(ImgA, 50, 100, "Hello, world");
float red[] = { 1, 0, 0, 1 };
ImageBufAlgo::render_text (ImgA, 100, 200, "Go Big Red!",
60, "" /*font name*/, red);
ImageBufAlgo::render_text(ImgA, 100, 200, "Go Big Red!", 60,
"" /*font name*/, cspan<float>(red));

float white[] = { 1, 1, 1, 1 };
ImageBufAlgo::render_text (ImgB, 320, 240, "Centered",
60, "" /*font name*/, white,
ImageBufAlgo::render_text(ImgB, 320, 240, "Centered", 60, "" /*font name*/,
cspan<float>(white),
ImageBufAlgo::TextAlignX::Center,
ImageBufAlgo::TextAlignY::Center);
// END-imagebufalgo-text1
Expand All @@ -235,6 +245,138 @@ void example_text2()

// Section: Image transformation and data movement

void example_channels()
{
ImageBuf RGBA ("grid.exr");

// BEGIN-imagebufalgo-channels
// Copy the first 3 channels of an RGBA, drop the alpha
ImageBuf RGB = ImageBufAlgo::channels (RGBA, 3, {} /*default ordering*/);

// Copy just the alpha channel, making a 1-channel image
ImageBuf Alpha = ImageBufAlgo::channels (RGBA, 1, 3 /*alpha_channel*/);

// Swap the R and B channels
ImageBuf BRGA;
bool success = ImageBufAlgo::channels (
BRGA, RGBA, 4, { 2, 1, 0, 3 }, {}, { "R", "G", "B", "A" });

// Add an alpha channel with value 1.0 everywhere to an RGB image,
// keep the other channels with their old ordering, values, and
// names.
RGBA = ImageBufAlgo::channels (
RGB, 4, { 0, 1, 2, -1 },
{ 0 /*ignore*/, 0 /*ignore*/, 0 /*ignore*/, 1.0 },
{ "", "", "", "A" });
// END-imagebufalgo-channels

RGBA.write("channels-rgba.exr");
RGB.write("channels-rgb.exr");
Alpha.write("channels-alpha.exr");
BRGA.write("channels-brga.exr");
}

void example_channel_append()
{
ImageBuf Z (ImageSpec (640, 480, 1, TypeDesc::FLOAT));

// BEGIN-imagebufalgo-channel-append
ImageBuf RGBA ("grid.exr");
ImageBuf RGBAZ = ImageBufAlgo::channel_append (RGBA, Z);
// END-imagebufalgo-channel-append

RGBAZ.write("channel-append.exr");
}

void example_copy()
{
// BEGIN-imagebufalgo-copy
// Set B to be a copy of A, but converted to float
ImageBuf A ("grid.exr");
ImageBuf B = ImageBufAlgo::copy (A, TypeDesc::FLOAT);
// END-imagebufalgo-copy

B.write("copy.exr");
}

void example_crop()
{
// BEGIN-imagebufalgo-crop
// Set B to be a 200x100 region of A starting at (50,50), trimming
// the exterior away but leaving that region in its original position.
ImageBuf A ("grid.exr");
ImageBuf B = ImageBufAlgo::crop (A, ROI(50, 250, 50, 150));
// END-imagebufalgo-crop

B.write("crop.exr");
}

void example_cut()
{
// BEGIN-imagebufalgo-cut
// Set B to be a 200x100 region of A starting at (50,50), but
// moved to the upper left corner so its new origin is (0,0).
ImageBuf A ("grid.exr");
ImageBuf B = ImageBufAlgo::cut (A, ROI(50,250,50,150));
// END-imagebufalgo-cut

B.write("cut.exr");
}

void example_paste()
{
// BEGIN-imagebufalgo-paste
// Paste Fg on top of Bg, offset by (100,100)
ImageBuf Bg ("grid.exr");
ImageBuf Fg ("tahoe.tif");
ImageBufAlgo::paste (Bg, 100, 100, 0, 0, Fg);
// END-imagebufalgo-paste

Bg.write("paste.exr");
}

void example_rotate_n()
{
// BEGIN-imagebufalgo-rotate-n
ImageBuf A ("grid.exr");
ImageBuf R90 = ImageBufAlgo::rotate90 (A);
ImageBuf R180 = ImageBufAlgo::rotate180 (A);
ImageBuf R270 = ImageBufAlgo::rotate270 (A);
// END-imagebufalgo-rotate-n

R90.write("rotate-90.exr");
R180.write("rotate-180.exr");
R270.write("rotate-270.exr");
}

void example_flip_flop_transpose()
{
// BEGIN-imagebufalgo-flip-flop-transpose
ImageBuf A ("grid.exr");
ImageBuf B1 = ImageBufAlgo::flip (A);
ImageBuf B2 = ImageBufAlgo::flop (A);
ImageBuf B3 = ImageBufAlgo::transpose (A);
// END-imagebufalgo-flip-flop-transpose

B1.write("flip.exr");
B2.write("flop.exr");
B3.write("transpose.exr");
}

void example_reorient()
{
ImageBuf tmp ("grid.exr");
tmp.specmod().attribute("Orientation", 8);
tmp.write("grid-vertical.exr");

// BEGIN-imagebufalgo-reorient
ImageBuf A ("grid-vertical.exr");
A = ImageBufAlgo::reorient (A);
// END-imagebufalgo-reorient

A.write("reorient.exr");
}

void example_circular_shift()
{
// BEGIN-imagebufalgo-cshift
Expand All @@ -244,6 +386,54 @@ void example_circular_shift()
// END-imagebufalgo-cshift
}

void example_rotate()
{
// BEGIN-imagebufalgo-rotate-angle
ImageBuf Src ("grid.exr");
ImageBuf Dst = ImageBufAlgo::rotate (Src, 45.0);
// END-imagebufalgo-rotate-angle
}

void example_resize()
{
// BEGIN-imagebufalgo-resize
// Resize the image to 640x480, using the default filter
ImageBuf Src ("grid.exr");
ROI roi (0, 640, 0, 480, 0, 1, /*chans:*/ 0, Src.nchannels());
ImageBuf Dst = ImageBufAlgo::resize (Src, {}, roi);
// END-imagebufalgo-resize
}

void example_resample()
{
// BEGIN-imagebufalgo-resample
// Resample quickly to 320x240, with default interpolation
ImageBuf Src ("grid.exr");
ROI roi (0, 320, 0, 240, 0, 1, /*chans:*/ 0, Src.nchannels());
ImageBuf Dst = ImageBufAlgo::resample (Src, true, roi);
// END-imagebufalgo-resample
}

void example_fit()
{
// BEGIN-imagebufalgo-fit
// Resize to fit into a max of 640x480, preserving the aspect ratio
ImageBuf Src ("grid.exr");
ROI roi (0, 640, 0, 480, 0, 1, /*chans:*/ 0, Src.nchannels());
ImageBuf Dst = ImageBufAlgo::fit (Src, {}, roi);
// END-imagebufalgo-fit
}

void example_warp()
{
// BEGIN-imagebufalgo-warp
Imath::M33f M ( 0.7071068, 0.7071068, 0,
-0.7071068, 0.7071068, 0,
20, -8.284271, 1);
ImageBuf Src ("grid.exr");
ImageBuf Dst = ImageBufAlgo::warp(Src, M, { { "filtername", "lanczos3" } });
// END-imagebufalgo-warp
}


// Section: Image Arithmetic
Expand Down Expand Up @@ -284,9 +474,6 @@ void example_make_texture()
}





int main(int /*argc*/, char** /*argv*/)
{
// Each example function needs to get called here, or it won't execute
Expand All @@ -310,7 +497,21 @@ int main(int /*argc*/, char** /*argv*/)
example_text2();

// Section: Image transformation and data movement
example_channels();
example_channel_append();
example_copy();
example_crop();
example_cut();
example_paste();
example_rotate_n();
example_flip_flop_transpose();
example_reorient();
example_circular_shift();
example_rotate();
example_resize();
example_resample();
example_fit();
example_warp();

// Section: Image Arithmetic

Expand Down
Loading

0 comments on commit b0cb53d

Please sign in to comment.