Blame IlmImfExamples/drawImage.cpp

Packit 0d464f
///////////////////////////////////////////////////////////////////////////
Packit 0d464f
//
Packit 0d464f
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
Packit 0d464f
// Digital Ltd. LLC
Packit 0d464f
// 
Packit 0d464f
// All rights reserved.
Packit 0d464f
//
Packit 0d464f
// Redistribution and use in source and binary forms, with or without
Packit 0d464f
// modification, are permitted provided that the following conditions are
Packit 0d464f
// met:
Packit 0d464f
// *       Redistributions of source code must retain the above copyright
Packit 0d464f
// notice, this list of conditions and the following disclaimer.
Packit 0d464f
// *       Redistributions in binary form must reproduce the above
Packit 0d464f
// copyright notice, this list of conditions and the following disclaimer
Packit 0d464f
// in the documentation and/or other materials provided with the
Packit 0d464f
// distribution.
Packit 0d464f
// *       Neither the name of Industrial Light & Magic nor the names of
Packit 0d464f
// its contributors may be used to endorse or promote products derived
Packit 0d464f
// from this software without specific prior written permission. 
Packit 0d464f
// 
Packit 0d464f
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 0d464f
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 0d464f
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 0d464f
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit 0d464f
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit 0d464f
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 0d464f
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit 0d464f
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit 0d464f
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit 0d464f
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 0d464f
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 0d464f
//
Packit 0d464f
///////////////////////////////////////////////////////////////////////////
Packit 0d464f
Packit 0d464f
Packit 0d464f
Packit 0d464f
//-----------------------------------------------------------------------------
Packit 0d464f
//
Packit 0d464f
//	Functions that algorithmically generate images, so that
Packit 0d464f
//	the code examples for image file reading and writing have
Packit 0d464f
//	data they can work with.
Packit 0d464f
//	Note that it is not necessary to study the code below in
Packit 0d464f
//	order to understand how the file I/O code examples work.
Packit 0d464f
//
Packit 0d464f
//-----------------------------------------------------------------------------
Packit 0d464f
Packit 0d464f
Packit 0d464f
#include "drawImage.h"
Packit 0d464f
Packit 0d464f
#include <math.h>
Packit 0d464f
#include <stdlib.h>
Packit 0d464f
#include <float.h>
Packit 0d464f
#include <algorithm>
Packit 0d464f
Packit 0d464f
#include "namespaceAlias.h"
Packit 0d464f
using namespace IMF;
Packit 0d464f
using namespace std;
Packit 0d464f
Packit 0d464f
namespace
Packit 0d464f
{
Packit 0d464f
Packit 0d464f
float
Packit 0d464f
pw (float x, int y)
Packit 0d464f
{
Packit 0d464f
    float p = 1;
Packit 0d464f
Packit 0d464f
    while (y)
Packit 0d464f
    {
Packit 0d464f
	if (y & 1)
Packit 0d464f
	    p *= x;
Packit 0d464f
Packit 0d464f
	x *= x;
Packit 0d464f
	y >>= 1;
Packit 0d464f
    }
Packit 0d464f
Packit 0d464f
    return p;
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
sp (Array2D<Rgba> &px, int w, int h,
Packit 0d464f
    float xc, float yc, float rc,
Packit 0d464f
    float rd, float gn, float bl, float lm)
Packit 0d464f
{
Packit 0d464f
    int x1 = int (max ((float) floor (xc - rc),  0.0f));
Packit 0d464f
    int x2 = int (min ((float) ceil  (xc + rc), w - 1.0f));
Packit 0d464f
    int y1 = int (max ((float) floor (yc - rc),  0.0f));
Packit 0d464f
    int y2 = int (min ((float) ceil  (yc + rc), h - 1.0f));
Packit 0d464f
Packit 0d464f
    for (int y = y1; y <= y2; ++y)
Packit 0d464f
    {
Packit 0d464f
	for (int x = x1; x <= x2; ++x)
Packit 0d464f
	{
Packit 0d464f
	    float xl = (x - xc) / rc;
Packit 0d464f
	    float yl = (y - yc) / rc;
Packit 0d464f
	    float r  = sqrt (xl * xl + yl * yl);
Packit 0d464f
Packit 0d464f
	    if (r >= 1)
Packit 0d464f
		continue;
Packit 0d464f
Packit 0d464f
	    float a = 1;
Packit 0d464f
Packit 0d464f
	    if (r * rc > rc - 1)
Packit 0d464f
		a = rc - r * rc;
Packit 0d464f
Packit 0d464f
	    float zl = sqrt (1 - r * r);
Packit 0d464f
	    float dl = xl * 0.42426 - yl * 0.56568 + zl * 0.70710;
Packit 0d464f
Packit 0d464f
	    if (dl < 0)
Packit 0d464f
		dl *= -0.1;
Packit 0d464f
Packit 0d464f
	    float hl = pw (dl, 50) * 4;
Packit 0d464f
	    float dr = (dl + hl) * rd;
Packit 0d464f
	    float dg = (dl + hl) * gn;
Packit 0d464f
	    float db = (dl + hl) * bl;
Packit 0d464f
Packit 0d464f
	    Rgba &p = px[y][x];
Packit 0d464f
	    p.r = p.r * (1 - a) + dr * lm * a;
Packit 0d464f
	    p.g = p.g * (1 - a) + dg * lm * a;
Packit 0d464f
	    p.b = p.b * (1 - a) + db * lm * a;
Packit 0d464f
	    p.a = 1 - (1 - p.a) * (1 - a);
Packit 0d464f
	}
Packit 0d464f
    }
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
zsp (Array2D<half> &gpx, Array2D<float> &zpx, int w, int h,
Packit 0d464f
     float xc, float yc, float zc, float rc, float gn)
Packit 0d464f
{
Packit 0d464f
    int x1 = int (max ((float) floor (xc - rc),  0.0f));
Packit 0d464f
    int x2 = int (min ((float) ceil  (xc + rc), w - 1.0f));
Packit 0d464f
    int y1 = int (max ((float) floor (yc - rc),  0.0f));
Packit 0d464f
    int y2 = int (min ((float) ceil  (yc + rc), h - 1.0f));
Packit 0d464f
Packit 0d464f
    for (int x = x1; x <= x2; ++x)
Packit 0d464f
    {
Packit 0d464f
	for (int y = y1; y <= y2; ++y)
Packit 0d464f
	{
Packit 0d464f
	    float xl = (x - xc) / rc;
Packit 0d464f
	    float yl = (y - yc) / rc;
Packit 0d464f
	    float r  = sqrt (xl * xl + yl * yl);
Packit 0d464f
Packit 0d464f
	    if (r >= 1)
Packit 0d464f
		continue;
Packit 0d464f
Packit 0d464f
	    float a = 1;
Packit 0d464f
Packit 0d464f
	    if (r * rc > rc - 1)
Packit 0d464f
		a = rc - r * rc;
Packit 0d464f
Packit 0d464f
	    float zl = sqrt (1 - r * r);
Packit 0d464f
	    float zp = zc - rc * zl;
Packit 0d464f
Packit 0d464f
	    if (zp >= zpx[y][x])
Packit 0d464f
		continue;
Packit 0d464f
Packit 0d464f
	    float dl = xl * 0.42426 - yl * 0.56568 + zl * 0.70710;
Packit 0d464f
Packit 0d464f
	    if (dl < 0)
Packit 0d464f
		dl *= -0.1;
Packit 0d464f
Packit 0d464f
	    float hl = pw (dl, 50) * 4;
Packit 0d464f
	    float dg = (dl + hl) * gn;
Packit 0d464f
Packit 0d464f
	    gpx[y][x] = dg;
Packit 0d464f
	    zpx[y][x] = zp;
Packit 0d464f
	}
Packit 0d464f
    }
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
inline float
Packit 0d464f
z (float k)
Packit 0d464f
{
Packit 0d464f
    k = 2 * (k - int (k));
Packit 0d464f
    return (k < 1)? k: 2 - k;
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
inline void
Packit 0d464f
clear (Rgba &color)
Packit 0d464f
{
Packit 0d464f
    color.r = 0;
Packit 0d464f
    color.g = 0;
Packit 0d464f
    color.b = 0;
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
inline void
Packit 0d464f
clear (GZ &gz)
Packit 0d464f
{
Packit 0d464f
    gz.g = 0;
Packit 0d464f
    gz.z = 0;
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
add (float k, Rgba &color)
Packit 0d464f
{
Packit 0d464f
    color.a = k;
Packit 0d464f
    k *= 4;
Packit 0d464f
    color.r += 0.1f + 4 * z (k);
Packit 0d464f
    color.g += 0.1f + 4 * z (k + .33333f);
Packit 0d464f
    color.b += 0.1f + 4 * z (k + .66667f);
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
add (float k, GZ &gz)
Packit 0d464f
{
Packit 0d464f
    k *= 5;
Packit 0d464f
    gz.g += 4 * z (k);
Packit 0d464f
    gz.z = k;
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
inline void
Packit 0d464f
scale (float f, Rgba &color)
Packit 0d464f
{
Packit 0d464f
    color.r *= f;
Packit 0d464f
    color.g *= f;
Packit 0d464f
    color.b *= f;
Packit 0d464f
    color.a *= f;
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
inline void
Packit 0d464f
scale (float f, GZ &gz)
Packit 0d464f
{
Packit 0d464f
    gz.g *= f;
Packit 0d464f
    gz.z *= f;
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
template <class P>
Packit 0d464f
void
Packit 0d464f
mndl (Array2D 

&px,

Packit 0d464f
      int w, int h,
Packit 0d464f
      int xMin, int xMax,
Packit 0d464f
      int yMin, int yMax,
Packit 0d464f
      int xSamples, int ySamples,
Packit 0d464f
      double rMin,
Packit 0d464f
      double rMax,
Packit 0d464f
      double iMin,
Packit 0d464f
      double aspect,
Packit 0d464f
      double rSeed,
Packit 0d464f
      double iSeed)
Packit 0d464f
{
Packit 0d464f
    if (xSamples > 6)
Packit 0d464f
	xSamples = 6;
Packit 0d464f
Packit 0d464f
    if (ySamples > 6)
Packit 0d464f
	ySamples = 6;
Packit 0d464f
Packit 0d464f
    double iMax = iMin + aspect * (rMax - rMin) * h / w;
Packit 0d464f
    double sx = double (rMax - rMin) / w;
Packit 0d464f
    double sy = double (iMax - iMin) / h;
Packit 0d464f
    double tx = 1.f / xSamples;
Packit 0d464f
    double ty = 1.f / ySamples;
Packit 0d464f
    float  t  = tx * ty;
Packit 0d464f
Packit 0d464f
    for (int y = yMin; y < yMax; ++y)
Packit 0d464f
    {
Packit 0d464f
        for (int x = xMin; x < xMax; ++x)
Packit 0d464f
        {
Packit 0d464f
            P &p = px[y - yMin][x - xMin];
Packit 0d464f
Packit 0d464f
	    clear (p);
Packit 0d464f
Packit 0d464f
	    for (int i = 0; i < xSamples; ++i)
Packit 0d464f
            {
Packit 0d464f
		for (int j = 0; j < ySamples; ++j)
Packit 0d464f
                {
Packit 0d464f
                    const double a = rMin + sx * (x + i * tx);
Packit 0d464f
		    const double b = iMin + sy * (y + j * ty);
Packit 0d464f
		    const double sMax = 100;
Packit 0d464f
		    const int kMax = 256;
Packit 0d464f
                    double r = rSeed;
Packit 0d464f
		    double i = iSeed;
Packit 0d464f
		    double s = 0;
Packit 0d464f
                    int k = 0;
Packit 0d464f
Packit 0d464f
                    while (k < kMax && s < sMax)
Packit 0d464f
                    {
Packit 0d464f
                        s = r * r - i * i;
Packit 0d464f
                        i = 2 * r * i + b;
Packit 0d464f
                        r = s + a;
Packit 0d464f
                        k++;
Packit 0d464f
                    }
Packit 0d464f
Packit 0d464f
		    add (k / float (kMax), p);
Packit 0d464f
                }
Packit 0d464f
            }
Packit 0d464f
Packit 0d464f
	    scale (t, p);
Packit 0d464f
        }
Packit 0d464f
    }
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
} // namespace
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
drawImage1 (Array2D<Rgba> &px, int w, int h)
Packit 0d464f
{
Packit 0d464f
    for (int y = 0; y < h; ++y)
Packit 0d464f
    {
Packit 0d464f
	for (int x = 0; x < w; ++x)
Packit 0d464f
	{
Packit 0d464f
	    Rgba &p = px[y][x];
Packit 0d464f
	    p.r = 0;
Packit 0d464f
	    p.g = 0;
Packit 0d464f
	    p.b = 0;
Packit 0d464f
	    p.a = 0;
Packit 0d464f
	}
Packit 0d464f
    }
Packit 0d464f
Packit 0d464f
    int n = 5600;
Packit 0d464f
Packit 0d464f
    for (int i = 0; i < n; ++i)
Packit 0d464f
    {
Packit 0d464f
	float t = (i * 2.0 * M_PI) / n;
Packit 0d464f
	float xp = sin (t * 2.0) + 0.2 * sin (t * 15.0);
Packit 0d464f
	float yp = cos (t * 3.0) + 0.2 * cos (t * 15.0);
Packit 0d464f
	float r = float (i + 1) / float (n);
Packit 0d464f
	float xq = xp + 0.3 * r * sin (t * 80.0);
Packit 0d464f
	float yq = yp + 0.3 * r * cos (t * 80.0);
Packit 0d464f
	float xr = xp + 0.3 * r * sin (t * 80.0 + M_PI / 2);
Packit 0d464f
	float yr = yp + 0.3 * r * cos (t * 80.0 + M_PI / 2);
Packit 0d464f
Packit 0d464f
	if (i % 10 == 0)
Packit 0d464f
	    sp (px, w, h,
Packit 0d464f
		xp * w / 3 + w / 2, yp * h / 3 + h / 2,
Packit 0d464f
		w * 0.05 * r,
Packit 0d464f
		2.0, 0.8, 0.1,
Packit 0d464f
		0.5 * r * r);
Packit 0d464f
Packit 0d464f
	sp (px, w, h,
Packit 0d464f
	    xq * w / 3 + w / 2, yq * h / 3 + h / 2,
Packit 0d464f
	    w * 0.01 * r,
Packit 0d464f
	    0.7, 0.2, 2.0,
Packit 0d464f
	    0.5 * r * r);
Packit 0d464f
Packit 0d464f
	sp (px, w, h,
Packit 0d464f
	    xr * w / 3 + w / 2, yr * h / 3 + h / 2,
Packit 0d464f
	    w * 0.01 * r,
Packit 0d464f
	    0.2, 1.5, 0.1,
Packit 0d464f
	    0.5 * r * r);
Packit 0d464f
    }
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
drawImage2 (Array2D<half> &gpx, Array2D<float> &zpx, int w, int h)
Packit 0d464f
{
Packit 0d464f
    for (int y = 0; y < h; ++y)
Packit 0d464f
    {
Packit 0d464f
	for (int x = 0; x < w; ++x)
Packit 0d464f
	{
Packit 0d464f
	    gpx[y][x] = 0;
Packit 0d464f
	    zpx[y][x] = FLT_MAX;
Packit 0d464f
	}
Packit 0d464f
    }
Packit 0d464f
Packit 0d464f
    int n = 2000;
Packit 0d464f
Packit 0d464f
    for (int i = 0; i < n; ++i)
Packit 0d464f
    {
Packit 0d464f
	float t = (i * 2.0 * M_PI) / n;
Packit 0d464f
	float xp = sin (t * 4.0) + 0.2 * sin (t * 15.0);
Packit 0d464f
	float yp = cos (t * 3.0) + 0.2 * cos (t * 15.0);
Packit 0d464f
	float zp = sin (t * 5.0);
Packit 0d464f
	float rd = 0.7 + 0.3 * sin (t * 15.0);
Packit 0d464f
	float gn = 0.5 - 0.5 * zp + 0.2;
Packit 0d464f
Packit 0d464f
	zsp (gpx, zpx, w, h,
Packit 0d464f
	     xp * w / 3 + w / 2,
Packit 0d464f
	     yp * h / 3 + h / 2,
Packit 0d464f
	     zp * w + 3 * w,
Packit 0d464f
	     w * rd * 0.05,
Packit 0d464f
	     2.5 * gn * gn);
Packit 0d464f
    }
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
drawImage3 (Array2D<Rgba> &px,
Packit 0d464f
            int w, int h,
Packit 0d464f
            int xMin, int xMax,
Packit 0d464f
            int yMin, int yMax,
Packit 0d464f
            int xLevel, int yLevel)
Packit 0d464f
{
Packit 0d464f
    mndl (px,
Packit 0d464f
	  w, h,
Packit 0d464f
	  xMin, xMax,
Packit 0d464f
	  yMin, yMax,
Packit 0d464f
	  (1 << xLevel), (1 << yLevel),
Packit 0d464f
	  0.328, 0.369,
Packit 0d464f
	  0.5,
Packit 0d464f
	  double (1 << yLevel) / double (1 << xLevel),
Packit 0d464f
	  -0.713, 0.9738);
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
drawImage4 (Array2D<Rgba> &px,
Packit 0d464f
            int w, int h,
Packit 0d464f
            int xMin, int xMax,
Packit 0d464f
            int yMin, int yMax,
Packit 0d464f
            int xLevel, int yLevel)
Packit 0d464f
{
Packit 0d464f
    mndl (px,
Packit 0d464f
	  w, h,
Packit 0d464f
	  xMin, xMax,
Packit 0d464f
	  yMin, yMax,
Packit 0d464f
	  (1 << xLevel), (1 << yLevel),
Packit 0d464f
	  0.3247, 0.33348,
Packit 0d464f
	  0.4346,
Packit 0d464f
	  double (1 << yLevel) / double (1 << xLevel),
Packit 0d464f
	  0.4, -0.765);
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
drawImage5 (Array2D<Rgba> &px,
Packit 0d464f
            int w, int h,
Packit 0d464f
            int xMin, int xMax,
Packit 0d464f
            int yMin, int yMax,
Packit 0d464f
            int xLevel, int yLevel)
Packit 0d464f
{
Packit 0d464f
    mndl (px,
Packit 0d464f
	  w, h,
Packit 0d464f
	  xMin, xMax,
Packit 0d464f
	  yMin, yMax,
Packit 0d464f
	  (1 << xLevel), (1 << yLevel),
Packit 0d464f
	  0.2839, 0.2852,
Packit 0d464f
	  0.00961,
Packit 0d464f
	  double (1 << yLevel) / double (1 << xLevel),
Packit 0d464f
	  0.25, 0.31);
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
drawImage6 (Array2D<GZ> &px, int w, int h)
Packit 0d464f
{
Packit 0d464f
    mndl (px,
Packit 0d464f
	  w, h,
Packit 0d464f
	  0, w,
Packit 0d464f
	  0, h,
Packit 0d464f
	  3, 3,
Packit 0d464f
	  -2.5, 1.0,
Packit 0d464f
	  -1.3333,
Packit 0d464f
	  1,
Packit 0d464f
	  0, 0);
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
drawImage7 (Array<Rgba> &px, int w, int h, int y)
Packit 0d464f
{
Packit 0d464f
    for (int x = 0; x < w; ++x)
Packit 0d464f
    {
Packit 0d464f
	float xc = x - w / 2;
Packit 0d464f
	float yc = y - h / 2;
Packit 0d464f
	float a = atan2 (xc, yc);
Packit 0d464f
	float r = sqrt (xc * xc + yc * yc);
Packit 0d464f
Packit 0d464f
	Rgba &p = px[x];
Packit 0d464f
	p.r = sin (3.0f * a + 0.3f * sin (0.10f * r)) * 0.5f + 0.5f;
Packit 0d464f
	p.g = sin (3.0f * a + 0.3f * sin (0.11f * r)) * 0.5f + 0.5f;
Packit 0d464f
	p.b = sin (3.0f * a + 0.3f * sin (0.12f * r)) * 0.5f + 0.5f;
Packit 0d464f
	p.a = 1;
Packit 0d464f
    }
Packit 0d464f
}