<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2014-2015 Darrell Wright
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files( the "Software" ), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "history_pages.h"
#include <iostream>
#include <streambuf>
#include <fstream>
#include <cstdlib>
#include <chrono>

template<typename Data>
void display( Data const & data ) {
	for( auto it = data.begin( ); it != data.end( ); ++it ) {
		if( it != data.begin( ) ) {
			std::cout << " ";
		}
		std::cout << std::hex << std::setw( 2 ) << std::setfill( '0' ) << static_cast<int>(*it);
	}
}

auto current_year( ) {
	auto t = std::chrono::system_clock::now( );
	std::time_t now_c = std::chrono::system_clock::to_time_t( t );
    struct tm *parts = std::localtime( &now_c );
	uint16_t result = 1900 + parts->tm_year;
	return result;
}

std::string read_file( std::string file_name ) {
	std::ifstream ifs( file_name.c_str( ) );
	std::string result;

	ifs.seekg( 0, std::ios::end );
	result.reserve( ifs.tellg( ) );
	ifs.seekg( 0, std::ios::beg );

	result.assign( (std::istreambuf_iterator<char>( ifs )), std::istreambuf_iterator<char>( ) );

	return result;
}

int main( int argc, char** argv ) {
	assert( argc > 2 );
	daw::history::pump_model_t pump_model( argv[1] );

	auto data = read_file( argv[2] );

	std::vector<uint8_t> v;
	for( size_t n = 0; n < data.size( ); n += 2 ) {
		while( std::isspace( data[n] ) ) {
			++n;
		}
		char tmp[3] = { data[n], data[n + 1], 0 };
		v.push_back( static_cast<uint8_t>(strtol( tmp, nullptr, 16 )) );
	}
	if( v.back( ) == 0 ) {
		v.pop_back( ); // null terminator
	}
	v.pop_back( ); // crc
	v.pop_back( ); // crc
	auto range = daw::range::make_range( v.data( ), v.data( ) + v.size( ) );

	std::vector<std::unique_ptr<daw::history::history_entry_obj>> entries;
	size_t pos = 0;

	auto good_item = []( auto const & i ) {
		if( !i ) {
			return false;
		}
		if( !i->timestamp( ) ) {
			return false;
		}
		uint16_t const item_year = i->timestamp( )->date.year;
		static uint16_t const now_year = current_year( );
		return item_year == now_year;
	};

	while( !range.at_end( ) ) {
		std::cout << std::dec << std::dec << pos << "/" << v.size( ) << ": ";
		auto item = daw::history::create_history_entry( range, pump_model, pos );
		if( item ) {
			std::cout << *item;
			entries.push_back( std::move( item ) );
		} else {
			std::cout << "ERROR: data( ";
			auto err_start = pos;
			safe_advance( range, 1 );
			while( !range.at_end( ) && (range[0] == 0 || !(item = daw::history::create_history_entry( range, pump_model, pos )) || !good_item( item ) )) {
				safe_advance( range, 1 );
				++pos;
			}
			auto offset = item ? item->size( ) - 1 : 0;
			std::cout << (pos-(err_start+offset)) << " ) { ";
			display( daw::range::make_range( v.data( ) + err_start, v.data( ) + pos - offset ) );
			std::cout << " }\n";
			if( !range.at_end( ) ) {
				std::cout << std::dec << std::dec << (pos-offset) << "/" << v.size( ) << ": " << *item;
				entries.push_back( std::move( item ) );
			}
		}
		std::cout << "\n";
	}
	return EXIT_SUCCESS;
}

<commit_msg>Fixed output of size<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2014-2015 Darrell Wright
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files( the "Software" ), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "history_pages.h"
#include <iostream>
#include <streambuf>
#include <fstream>
#include <cstdlib>
#include <chrono>

template<typename Data>
void display( Data const & data ) {
	for( auto it = data.begin( ); it != data.end( ); ++it ) {
		if( it != data.begin( ) ) {
			std::cout << " ";
		}
		std::cout << std::hex << std::setw( 2 ) << std::setfill( '0' ) << static_cast<int>(*it);
	}
}

auto current_year( ) {
	auto t = std::chrono::system_clock::now( );
	std::time_t now_c = std::chrono::system_clock::to_time_t( t );
	struct tm *parts = std::localtime( &now_c );
	uint16_t result = 1900 + parts->tm_year;
	return result;
}

std::string read_file( std::string file_name ) {
	std::ifstream ifs( file_name.c_str( ) );
	std::string result;

	ifs.seekg( 0, std::ios::end );
	result.reserve( ifs.tellg( ) );
	ifs.seekg( 0, std::ios::beg );

	result.assign( (std::istreambuf_iterator<char>( ifs )), std::istreambuf_iterator<char>( ) );

	return result;
}

int main( int argc, char** argv ) {
	assert( argc > 2 );
	daw::history::pump_model_t pump_model( argv[1] );

	auto data = read_file( argv[2] );

	std::vector<uint8_t> v;
	for( size_t n = 0; n < data.size( ); n += 2 ) {
		while( std::isspace( data[n] ) ) {
			++n;
		}
		char tmp[3] = { data[n], data[n + 1], 0 };
		v.push_back( static_cast<uint8_t>(strtol( tmp, nullptr, 16 )) );
	}
	if( v.back( ) == 0 ) {
		v.pop_back( ); // null terminator
	}
	v.pop_back( ); // crc
	v.pop_back( ); // crc
	auto range = daw::range::make_range( v.data( ), v.data( ) + v.size( ) );

	std::vector<std::unique_ptr<daw::history::history_entry_obj>> entries;
	size_t pos = 0;

	auto good_item = []( auto const & i ) {
		if( !i ) {
			return false;
		}
		if( !i->timestamp( ) ) {
			return false;
		}
		uint16_t const item_year = i->timestamp( )->date.year;
		static uint16_t const now_year = current_year( );
		return item_year == now_year;
	};

	while( !range.at_end( ) ) {
		std::cout << std::dec << std::dec << pos << "/" << v.size( )-1 << ": ";
		auto item = daw::history::create_history_entry( range, pump_model, pos );
		if( item ) {
			std::cout << *item;
			entries.push_back( std::move( item ) );
		} else {
			std::cout << "ERROR: data( ";
			auto err_start = pos;
			safe_advance( range, 1 );
			while( !range.at_end( ) && (range[0] == 0 || !(item = daw::history::create_history_entry( range, pump_model, pos )) || !good_item( item ) )) {
				safe_advance( range, 1 );
				++pos;
			}
			auto offset = item ? item->size( ) - 1 : 0;
			std::cout << (pos-(err_start+offset)) << " ) { ";
			display( daw::range::make_range( v.data( ) + err_start, v.data( ) + pos - offset ) );
			std::cout << " }\n";
			if( !range.at_end( ) ) {
				std::cout << std::dec << std::dec << (pos-offset) << "/" << v.size( )-1 << ": " << *item;
				entries.push_back( std::move( item ) );
			}
		}
		std::cout << "\n";
	}
	return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include <osg/LightSource>

#include <osgDB/ReadFile>

#if defined(_MSC_VER)
#pragma warning( disable : 4505 )
#pragma warning( default : 4996 )
#endif
#include <fbxsdk.h>

#include "fbxReader.h"

osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxLight(FbxNode* pNode, int& nLightCount)
{
    const FbxLight* fbxLight = FbxCast<FbxLight>(pNode->GetNodeAttribute());

    if (!fbxLight)
    {
        return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
    }

    osg::Light* osgLight = new osg::Light;
    osg::LightSource* osgLightSource = new osg::LightSource;

    osgLightSource->setLight(osgLight);
    osgLight->setLightNum(nLightCount++);

    FbxLight::EType fbxLightType = fbxLight->LightType.IsValid() ?
        fbxLight->LightType.Get() : FbxLight::ePoint;

    osgLight->setPosition(osg::Vec4(0,0,0,fbxLightType != FbxLight::eDirectional));

    if (fbxLightType == FbxLight::eSpot)
    {
        double coneAngle = fbxLight->OuterAngle.Get();
        double hotSpot = fbxLight->InnerAngle.Get();
        const float MIN_HOTSPOT = 0.467532f;

        osgLight->setSpotCutoff(static_cast<float>(coneAngle));

        //Approximate the hotspot using the GL light exponent.
        // This formula maps a hotspot of 180 to exponent 0 (uniform light
        // distribution) and a hotspot of 45 to exponent 1 (effective light
        // intensity is attenuated by the cosine of the angle between the
        // direction of the light and the direction from the light to the vertex
        // being lighted). A hotspot close to 0 maps to exponent 128 (maximum).
        float exponent = (180.0f / (std::max)(static_cast<float>(hotSpot),
            MIN_HOTSPOT) - 1.0f) / 3.0f;
        osgLight->setSpotExponent(exponent);
    }

    if (fbxLight->DecayType.IsValid() &&
        fbxLight->DecayStart.IsValid())
    {
        double fbxDecayStart = fbxLight->DecayStart.Get();

        switch (fbxLight->DecayType.Get())
        {
        case FbxLight::eNone:
            break;
        case FbxLight::eLinear:
            osgLight->setLinearAttenuation(fbxDecayStart);
            break;
        case FbxLight::eQuadratic:
        case FbxLight::eCubic:
            osgLight->setQuadraticAttenuation(fbxDecayStart);
            break;
        }
    }

    osg::Vec3f osgDiffuseSpecular(1.0f, 1.0f, 1.0f);
    osg::Vec3f osgAmbient(0.0f, 0.0f, 0.0f);
    if (fbxLight->Color.IsValid())
    {
        FbxDouble3 fbxColor = fbxLight->Color.Get();
        osgDiffuseSpecular.set(
            static_cast<float>(fbxColor[0]),
            static_cast<float>(fbxColor[1]),
            static_cast<float>(fbxColor[2]));
    }
    if (fbxLight->Intensity.IsValid())
    {
        osgDiffuseSpecular *= static_cast<float>(fbxLight->Intensity.Get()) * 0.01f;
    }
    if (fbxLight->ShadowColor.IsValid())
    {
        FbxDouble3 fbxShadowColor = fbxLight->ShadowColor.Get();
        osgAmbient.set(
            static_cast<float>(fbxShadowColor[0]),
            static_cast<float>(fbxShadowColor[1]),
            static_cast<float>(fbxShadowColor[2]));
    }

    osgLight->setDiffuse(osg::Vec4f(osgDiffuseSpecular, 1.0f));
    osgLight->setSpecular(osg::Vec4f(osgDiffuseSpecular, 1.0f));
    osgLight->setAmbient(osg::Vec4f(osgAmbient, 1.0f));

    return osgDB::ReaderWriter::ReadResult(osgLightSource);
}
<commit_msg>From  Konstantin Matveyev, "Multiple light fix in FBX-importer"<commit_after>#include <osg/LightSource>

#include <osgDB/ReadFile>

#if defined(_MSC_VER)
#pragma warning( disable : 4505 )
#pragma warning( default : 4996 )
#endif
#include <fbxsdk.h>

#include "fbxReader.h"

osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxLight(FbxNode* pNode, int& nLightCount)
{
    const FbxLight* fbxLight = FbxCast<FbxLight>(pNode->GetNodeAttribute());

    if (!fbxLight)
    {
        return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
    }

    osg::Light* osgLight = new osg::Light;
    osgLight->setLightNum(nLightCount++);

    osg::LightSource* osgLightSource = new osg::LightSource;
    osgLightSource->setLight(osgLight);

    FbxLight::EType fbxLightType = fbxLight->LightType.IsValid() ?
        fbxLight->LightType.Get() : FbxLight::ePoint;

    osgLight->setPosition(osg::Vec4(0,0,0,fbxLightType != FbxLight::eDirectional));

    if (fbxLightType == FbxLight::eSpot)
    {
        double coneAngle = fbxLight->OuterAngle.Get();
        double hotSpot = fbxLight->InnerAngle.Get();
        const float MIN_HOTSPOT = 0.467532f;

        osgLight->setSpotCutoff(static_cast<float>(coneAngle));

        //Approximate the hotspot using the GL light exponent.
        // This formula maps a hotspot of 180 to exponent 0 (uniform light
        // distribution) and a hotspot of 45 to exponent 1 (effective light
        // intensity is attenuated by the cosine of the angle between the
        // direction of the light and the direction from the light to the vertex
        // being lighted). A hotspot close to 0 maps to exponent 128 (maximum).
        float exponent = (180.0f / (std::max)(static_cast<float>(hotSpot),
            MIN_HOTSPOT) - 1.0f) / 3.0f;
        osgLight->setSpotExponent(exponent);
    }

    if (fbxLight->DecayType.IsValid() &&
        fbxLight->DecayStart.IsValid())
    {
        double fbxDecayStart = fbxLight->DecayStart.Get();

        switch (fbxLight->DecayType.Get())
        {
        case FbxLight::eNone:
            break;
        case FbxLight::eLinear:
            osgLight->setLinearAttenuation(fbxDecayStart);
            break;
        case FbxLight::eQuadratic:
        case FbxLight::eCubic:
            osgLight->setQuadraticAttenuation(fbxDecayStart);
            break;
        }
    }

    osg::Vec3f osgDiffuseSpecular(1.0f, 1.0f, 1.0f);
    osg::Vec3f osgAmbient(0.0f, 0.0f, 0.0f);
    if (fbxLight->Color.IsValid())
    {
        FbxDouble3 fbxColor = fbxLight->Color.Get();
        osgDiffuseSpecular.set(
            static_cast<float>(fbxColor[0]),
            static_cast<float>(fbxColor[1]),
            static_cast<float>(fbxColor[2]));
    }
    if (fbxLight->Intensity.IsValid())
    {
        osgDiffuseSpecular *= static_cast<float>(fbxLight->Intensity.Get()) * 0.01f;
    }
    if (fbxLight->ShadowColor.IsValid())
    {
        FbxDouble3 fbxShadowColor = fbxLight->ShadowColor.Get();
        osgAmbient.set(
            static_cast<float>(fbxShadowColor[0]),
            static_cast<float>(fbxShadowColor[1]),
            static_cast<float>(fbxShadowColor[2]));
    }

    osgLight->setDiffuse(osg::Vec4f(osgDiffuseSpecular, 1.0f));
    osgLight->setSpecular(osg::Vec4f(osgDiffuseSpecular, 1.0f));
    osgLight->setAmbient(osg::Vec4f(osgAmbient, 1.0f));

    return osgDB::ReaderWriter::ReadResult(osgLightSource);
}
<|endoftext|>


<commit_before>/*
*
* Copyright (C) 2004 Mekensleep
*
*    Mekensleep
*    24 rue vieille du temple
*    75004 Paris
*       licensing@mekensleep.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* Author:
*  Igor Kravtchenko <igor@obraz.net>
*
*/

#include "hdrloader.h"

#include <math.h>
#include <memory.h>
#include <stdio.h>

typedef unsigned char RGBE[4];
#define R            0
#define G            1
#define B            2
#define E            3

#define  MINELEN    8                // minimum scanline length for encoding
#define  MAXELEN    0x7fff            // maximum scanline length for encoding

static void workOnRGBE(RGBE *scan, int len, float *cols);
static bool decrunch(RGBE *scanline, int len, FILE *file);
static bool oldDecrunch(RGBE *scanline, int len, FILE *file);

bool HDRLoader::isHDRFile(const char *_fileName)
{
    FILE *file;
    file = fopen(_fileName, "rb");
    if (!file)
        return false;

    char str[10];
    fread(str, 10, 1, file);
    fclose(file);

    if (memcmp(str, "#?RADIANCE", 10) && memcmp(str, "#?RGBE", 6))
        return false;

    return true;
}

bool HDRLoader::load(const char *_fileName, HDRLoaderResult &_res)
{
    int i;
    char str[200];
    FILE *file;

    file = fopen(_fileName, "rb");
    if (!file)
        return false;

    fread(str, 10, 1, file);
    if (memcmp(str, "#?RADIANCE", 10)) {
        fseek(file, 0, SEEK_SET);
        fread(str, 6, 1, file);
        if (memcmp(str, "#?RGBE", 6)) {
            fclose(file);
            return false;
        }
    }
    fseek(file, 1, SEEK_CUR);

    char cmd[2000];
    i = 0;
    char c = 0, oldc;
    while(true) {
        oldc = c;
        c = fgetc(file);
        if (c == 0xa && oldc == 0xa)
            break;
        cmd[i++] = c;
    }

    char reso[2000];
    i = 0;
    while(true) {
        c = fgetc(file);
        reso[i++] = c;
        if (c == 0xa)
            break;
    }

    int w, h;
    if (!sscanf(reso, "-Y %d +X %d", &h, &w)) {
        fclose(file);
        return false;
    }

    _res.width = w;
    _res.height = h;

    float *cols = new float[w * h * 3];
    _res.cols = cols;

    RGBE *scanline = new RGBE[w];
    if (!scanline) {
        fclose(file);
        return false;
    }

    // convert image
    cols += (h-1) * w * 3;
    for (int y = h - 1; y >= 0; y--) {
        if (decrunch(scanline, w, file) == false)
            break;
        workOnRGBE(scanline, w, cols);
        cols -= w * 3;
    }

    delete [] scanline;
    fclose(file);

    return true;
}

inline float convertComponent(int _expo, int _val)
{
    return ldexp( (float)_val / 256.0f, _expo);
}

void workOnRGBE(RGBE *_scan, int _len, float *_cols)
{
    int ii = 0;
    while (_len-- > 0) {
        int expo = _scan[0][E] - 128;
        _cols[0] = convertComponent(expo, _scan[0][R]);
        _cols[1] = convertComponent(expo, _scan[0][G]);
        _cols[2] = convertComponent(expo, _scan[0][B]);
        _cols += 3;
        _scan++;
        ii++;
    }
}

bool decrunch(RGBE *_scanline, int _len, FILE *_file)
{
    int  i, j;

    if (_len < MINELEN || _len > MAXELEN)
        return oldDecrunch(_scanline, _len, _file);

    i = fgetc(_file);
    if (i != 2) {
        fseek(_file, -1, SEEK_CUR);
        return oldDecrunch(_scanline, _len, _file);
    }

    _scanline[0][G] = fgetc(_file);
    _scanline[0][B] = fgetc(_file);
    i = fgetc(_file);

    if (_scanline[0][G] != 2 || _scanline[0][B] & 128) {
        _scanline[0][R] = 2;
        _scanline[0][E] = i;
        return oldDecrunch(_scanline + 1, _len - 1, _file);
    }

    // read each component
    for (i = 0; i < 4; i++) {
        for (j = 0; j < _len; ) {
            unsigned char code = fgetc(_file);
            if (code > 128) { // run
                code &= 127;
                unsigned char val = fgetc(_file);
                while (code--)
                    _scanline[j++][i] = val;
            }
            else  {    // non-run
                while(code--)
                    _scanline[j++][i] = fgetc(_file);
            }
        }
    }

    return feof(_file) ? false : true;
}

bool oldDecrunch(RGBE *_scanline, int _len, FILE *_file)
{
    int i;
    int rshift = 0;

    while (_len > 0) {
        _scanline[0][R] = fgetc(_file);
        _scanline[0][G] = fgetc(_file);
        _scanline[0][B] = fgetc(_file);
        _scanline[0][E] = fgetc(_file);
        if (feof(_file))
            return false;

        if (_scanline[0][R] == 1 &&
            _scanline[0][G] == 1 &&
            _scanline[0][B] == 1) {
                for (i = _scanline[0][E] << rshift; i > 0; i--) {
                    memcpy(&_scanline[0][0], &_scanline[-1][0], 4);
                    _scanline++;
                    _len--;
                }
                rshift += 8;
            }
        else {
            _scanline++;
            _len--;
            rshift = 0;
        }
    }
    return true;
}
<commit_msg>In the ldexp(,) call removed the /256.0f by replacing it with a -8 on the exponent.<commit_after>/*
*
* Copyright (C) 2004 Mekensleep
*
*    Mekensleep
*    24 rue vieille du temple
*    75004 Paris
*       licensing@mekensleep.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* Author:
*  Igor Kravtchenko <igor@obraz.net>
*
*/

#include "hdrloader.h"

#include <math.h>
#include <memory.h>
#include <stdio.h>

typedef unsigned char RGBE[4];
#define R            0
#define G            1
#define B            2
#define E            3

#define  MINELEN    8                // minimum scanline length for encoding
#define  MAXELEN    0x7fff            // maximum scanline length for encoding

static void workOnRGBE(RGBE *scan, int len, float *cols);
static bool decrunch(RGBE *scanline, int len, FILE *file);
static bool oldDecrunch(RGBE *scanline, int len, FILE *file);

bool HDRLoader::isHDRFile(const char *_fileName)
{
    FILE *file;
    file = fopen(_fileName, "rb");
    if (!file)
        return false;

    char str[10];
    fread(str, 10, 1, file);
    fclose(file);

    if (memcmp(str, "#?RADIANCE", 10) && memcmp(str, "#?RGBE", 6))
        return false;

    return true;
}

bool HDRLoader::load(const char *_fileName, HDRLoaderResult &_res)
{
    int i;
    char str[200];
    FILE *file;

    file = fopen(_fileName, "rb");
    if (!file)
        return false;

    fread(str, 10, 1, file);
    if (memcmp(str, "#?RADIANCE", 10)) {
        fseek(file, 0, SEEK_SET);
        fread(str, 6, 1, file);
        if (memcmp(str, "#?RGBE", 6)) {
            fclose(file);
            return false;
        }
    }
    fseek(file, 1, SEEK_CUR);

    char cmd[2000];
    i = 0;
    char c = 0, oldc;
    while(true) {
        oldc = c;
        c = fgetc(file);
        if (c == 0xa && oldc == 0xa)
            break;
        cmd[i++] = c;
    }

    char reso[2000];
    i = 0;
    while(true) {
        c = fgetc(file);
        reso[i++] = c;
        if (c == 0xa)
            break;
    }

    int w, h;
    if (!sscanf(reso, "-Y %d +X %d", &h, &w)) {
        fclose(file);
        return false;
    }

    _res.width = w;
    _res.height = h;

    float *cols = new float[w * h * 3];
    _res.cols = cols;

    RGBE *scanline = new RGBE[w];
    if (!scanline) {
        fclose(file);
        return false;
    }

    // convert image
    cols += (h-1) * w * 3;
    for (int y = h - 1; y >= 0; y--) {
        if (decrunch(scanline, w, file) == false)
            break;
        workOnRGBE(scanline, w, cols);
        cols -= w * 3;
    }

    delete [] scanline;
    fclose(file);

    return true;
}

inline float convertComponent(int _expo, int _val)
{
    return ldexp( _val, _expo-8);
}

void workOnRGBE(RGBE *_scan, int _len, float *_cols)
{
    int ii = 0;
    while (_len-- > 0) {
        int expo = _scan[0][E] - 128;
        _cols[0] = convertComponent(expo, _scan[0][R]);
        _cols[1] = convertComponent(expo, _scan[0][G]);
        _cols[2] = convertComponent(expo, _scan[0][B]);
        _cols += 3;
        _scan++;
        ii++;
    }
}

bool decrunch(RGBE *_scanline, int _len, FILE *_file)
{
    int  i, j;

    if (_len < MINELEN || _len > MAXELEN)
        return oldDecrunch(_scanline, _len, _file);

    i = fgetc(_file);
    if (i != 2) {
        fseek(_file, -1, SEEK_CUR);
        return oldDecrunch(_scanline, _len, _file);
    }

    _scanline[0][G] = fgetc(_file);
    _scanline[0][B] = fgetc(_file);
    i = fgetc(_file);

    if (_scanline[0][G] != 2 || _scanline[0][B] & 128) {
        _scanline[0][R] = 2;
        _scanline[0][E] = i;
        return oldDecrunch(_scanline + 1, _len - 1, _file);
    }

    // read each component
    for (i = 0; i < 4; i++) {
        for (j = 0; j < _len; ) {
            unsigned char code = fgetc(_file);
            if (code > 128) { // run
                code &= 127;
                unsigned char val = fgetc(_file);
                while (code--)
                    _scanline[j++][i] = val;
            }
            else  {    // non-run
                while(code--)
                    _scanline[j++][i] = fgetc(_file);
            }
        }
    }

    return feof(_file) ? false : true;
}

bool oldDecrunch(RGBE *_scanline, int _len, FILE *_file)
{
    int i;
    int rshift = 0;

    while (_len > 0) {
        _scanline[0][R] = fgetc(_file);
        _scanline[0][G] = fgetc(_file);
        _scanline[0][B] = fgetc(_file);
        _scanline[0][E] = fgetc(_file);
        if (feof(_file))
            return false;

        if (_scanline[0][R] == 1 &&
            _scanline[0][G] == 1 &&
            _scanline[0][B] == 1) {
                for (i = _scanline[0][E] << rshift; i > 0; i--) {
                    memcpy(&_scanline[0][0], &_scanline[-1][0], 4);
                    _scanline++;
                    _len--;
                }
                rshift += 8;
            }
        else {
            _scanline++;
            _len--;
            rshift = 0;
        }
    }
    return true;
}
<|endoftext|>


<commit_before>// ***************************************************************************
//
//   Generated automatically by genwrapper.
//   Please DO NOT EDIT this file!
//
// ***************************************************************************

#include <osgIntrospection/ReflectionMacros>
#include <osgIntrospection/TypedMethodInfo>
#include <osgIntrospection/StaticMethodInfo>
#include <osgIntrospection/Attributes>

#include <osg/CopyOp>
#include <osg/Group>
#include <osg/Node>
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/PagedLOD>
#include <osg/Referenced>

// Must undefine IN and OUT macros defined in Windows headers
#ifdef IN
#undef IN
#endif
#ifdef OUT
#undef OUT
#endif

TYPE_NAME_ALIAS(std::vector< osg::PagedLOD::PerRangeData >, osg::PagedLOD::PerRangeDataList)

BEGIN_OBJECT_REFLECTOR(osg::PagedLOD)
	I_DeclaringFile("osg/PagedLOD");
	I_BaseType(osg::LOD);
	I_Constructor0(____PagedLOD,
	               "",
	               "");
	I_ConstructorWithDefaults2(IN, const osg::PagedLOD &, x, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY,
	                           ____PagedLOD__C5_PagedLOD_R1__C5_CopyOp_R1,
	                           "Copy constructor using CopyOp to manage deep vs shallow copy. ",
	                           "");
	I_Method0(osg::Object *, cloneType,
	          Properties::VIRTUAL,
	          __osg_Object_P1__cloneType,
	          "clone an object of the same type as the node. ",
	          "");
	I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, copyop,
	          Properties::VIRTUAL,
	          __osg_Object_P1__clone__C5_osg_CopyOp_R1,
	          "return a clone of a node, with Object* return type. ",
	          "");
	I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj,
	          Properties::VIRTUAL,
	          __bool__isSameKindAs__C5_osg_Object_P1,
	          "return true if this and obj are of the same kind of object. ",
	          "");
	I_Method0(const char *, className,
	          Properties::VIRTUAL,
	          __C5_char_P1__className,
	          "return the name of the node's class type. ",
	          "");
	I_Method0(const char *, libraryName,
	          Properties::VIRTUAL,
	          __C5_char_P1__libraryName,
	          "return the name of the node's library. ",
	          "");
	I_Method1(void, accept, IN, osg::NodeVisitor &, nv,
	          Properties::VIRTUAL,
	          __void__accept__osg_NodeVisitor_R1,
	          "Visitor Pattern : calls the apply method of a NodeVisitor with this node's type. ",
	          "");
	I_Method1(void, traverse, IN, osg::NodeVisitor &, x,
	          Properties::VIRTUAL,
	          __void__traverse__NodeVisitor_R1,
	          "Traverse downwards : calls children's accept method with NodeVisitor. ",
	          "");
	I_Method1(bool, addChild, IN, osg::Node *, child,
	          Properties::VIRTUAL,
	          __bool__addChild__Node_P1,
	          "Add Node to Group. ",
	          "If node is not NULL and is not contained in Group then increment its reference count, add it to the child list and dirty the bounding sphere to force it to recompute on next getBound() and return true for success. Otherwise return false. Scene nodes can't be added as child nodes. ");
	I_Method3(bool, addChild, IN, osg::Node *, child, IN, float, min, IN, float, max,
	          Properties::VIRTUAL,
	          __bool__addChild__Node_P1__float__float,
	          "",
	          "");
	I_MethodWithDefaults6(bool, addChild, IN, osg::Node *, child, , IN, float, min, , IN, float, max, , IN, const std::string &, filename, , IN, float, priorityOffset, 0.0f, IN, float, priorityScale, 1.0f,
	                      Properties::VIRTUAL,
	                      __bool__addChild__Node_P1__float__float__C5_std_string_R1__float__float,
	                      "",
	                      "");
	I_MethodWithDefaults2(bool, removeChildren, IN, unsigned int, pos, , IN, unsigned int, numChildrenToRemove, 1,
	                      Properties::VIRTUAL,
	                      __bool__removeChildren__unsigned_int__unsigned_int,
	                      "Remove children from Group. ",
	                      "Note, must be override by subclasses of Group which add per child attributes. ");
	I_Method1(void, setDatabaseOptions, IN, osg::Referenced *, options,
	          Properties::NON_VIRTUAL,
	          __void__setDatabaseOptions__osg_Referenced_P1,
	          "Set the optional database osgDB::Options object to use when loaded children. ",
	          "");
	I_Method0(osg::Referenced *, getDatabaseOptions,
	          Properties::NON_VIRTUAL,
	          __osg_Referenced_P1__getDatabaseOptions,
	          "Get the optional database osgDB::Options object used when loaded children. ",
	          "");
	I_Method0(const osg::Referenced *, getDatabaseOptions,
	          Properties::NON_VIRTUAL,
	          __C5_osg_Referenced_P1__getDatabaseOptions,
	          "Get the optional database osgDB::Options object used when loaded children. ",
	          "");
	I_Method1(void, setDatabasePath, IN, const std::string &, path,
	          Properties::NON_VIRTUAL,
	          __void__setDatabasePath__C5_std_string_R1,
	          "Set the database path to prepend to children's filenames. ",
	          "");
	I_Method0(const std::string &, getDatabasePath,
	          Properties::NON_VIRTUAL,
	          __C5_std_string_R1__getDatabasePath,
	          "Get the database path used to prepend to children's filenames. ",
	          "");
	I_Method2(void, setFileName, IN, unsigned int, childNo, IN, const std::string &, filename,
	          Properties::NON_VIRTUAL,
	          __void__setFileName__unsigned_int__C5_std_string_R1,
	          "",
	          "");
	I_Method1(const std::string &, getFileName, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __C5_std_string_R1__getFileName__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumFileNames,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumFileNames,
	          "",
	          "");
	I_Method2(void, setPriorityOffset, IN, unsigned int, childNo, IN, float, priorityOffset,
	          Properties::NON_VIRTUAL,
	          __void__setPriorityOffset__unsigned_int__float,
	          "",
	          "");
	I_Method1(float, getPriorityOffset, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __float__getPriorityOffset__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumPriorityOffsets,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumPriorityOffsets,
	          "",
	          "");
	I_Method2(void, setPriorityScale, IN, unsigned int, childNo, IN, float, priorityScale,
	          Properties::NON_VIRTUAL,
	          __void__setPriorityScale__unsigned_int__float,
	          "",
	          "");
	I_Method1(float, getPriorityScale, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __float__getPriorityScale__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumPriorityScales,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumPriorityScales,
	          "",
	          "");
	I_Method2(void, setTimeStamp, IN, unsigned int, childNo, IN, double, timeStamp,
	          Properties::NON_VIRTUAL,
	          __void__setTimeStamp__unsigned_int__double,
	          "",
	          "");
	I_Method1(double, getTimeStamp, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __double__getTimeStamp__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumTimeStamps,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumTimeStamps,
	          "",
	          "");
	I_Method2(void, setFrameNumber, IN, unsigned int, childNo, IN, int, frameNumber,
	          Properties::NON_VIRTUAL,
	          __void__setFrameNumber__unsigned_int__int,
	          "",
	          "");
	I_Method1(double, getFrameNumber, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __double__getFrameNumber__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumFrameNumbers,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumFrameNumbers,
	          "",
	          "");
	I_Method1(osg::ref_ptr< osg::Referenced > &, getDatabaseRequest, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __osg_ref_ptrT1_osg_Referenced__R1__getDatabaseRequest__unsigned_int,
	          "Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests being carried on behalf of the DatabasePager. ",
	          "Note, in normal OSG usage you should not set this value yourself, as this will be managed by the osgDB::DatabasePager. ");
	I_Method1(const osg::ref_ptr< osg::Referenced > &, getDatabaseRequest, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __C5_osg_ref_ptrT1_osg_Referenced__R1__getDatabaseRequest__unsigned_int,
	          "Return the const DatabaseRequest object. ",
	          "");
	I_Method1(void, setFrameNumberOfLastTraversal, IN, int, frameNumber,
	          Properties::NON_VIRTUAL,
	          __void__setFrameNumberOfLastTraversal__int,
	          "Set the frame number of the last time that this PageLOD node was traversed. ",
	          "Note, this frame number is automatically set by the traverse() method for all traversals (update, cull etc.). ");
	I_Method0(int, getFrameNumberOfLastTraversal,
	          Properties::NON_VIRTUAL,
	          __int__getFrameNumberOfLastTraversal,
	          "Get the frame number of the last time that this PageLOD node was traversed. ",
	          "");
	I_Method1(void, setNumChildrenThatCannotBeExpired, IN, unsigned int, num,
	          Properties::NON_VIRTUAL,
	          __void__setNumChildrenThatCannotBeExpired__unsigned_int,
	          "Set the number of children that the PagedLOD must keep around, even if they are older than their expiry time. ",
	          "");
	I_Method0(unsigned int, getNumChildrenThatCannotBeExpired,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumChildrenThatCannotBeExpired,
	          "Get the number of children that the PagedLOD must keep around, even if they are older than their expiry time. ",
	          "");
	I_Method3(bool, removeExpiredChildren, IN, double, expiryTime, IN, int, expiryFrame, IN, osg::NodeList &, removedChildren,
	          Properties::VIRTUAL,
	          __bool__removeExpiredChildren__double__int__NodeList_R1,
	          "Remove the children from the PagedLOD which haven't been visited since specified expiry time and expiry frame number. ",
	          "The removed children are added to the removeChildren list passed into the method, this allows the children to be deleted later at the caller's discretion. Return true if children are removed, false otherwise. ");
	I_Method2(bool, releaseGLObjectsOnExpiredChildren, IN, double, releaseTime, IN, int, releaseFrame,
	          Properties::VIRTUAL,
	          __bool__releaseGLObjectsOnExpiredChildren__double__int,
	          "Release the GL Objects of the children from the PagedLOD which haven't been visited since specified expiry time and expiry frame number. ",
	          "Return true if any children have release called upon them, false otherwise. ");
	I_ProtectedMethod1(void, expandPerRangeDataTo, IN, unsigned int, pos,
	                   Properties::NON_VIRTUAL,
	                   Properties::NON_CONST,
	                   __void__expandPerRangeDataTo__unsigned_int,
	                   "",
	                   "");
	I_SimpleProperty(osg::Referenced *, DatabaseOptions,
	                 __osg_Referenced_P1__getDatabaseOptions,
	                 __void__setDatabaseOptions__osg_Referenced_P1);
	I_SimpleProperty(const std::string &, DatabasePath,
	                 __C5_std_string_R1__getDatabasePath,
	                 __void__setDatabasePath__C5_std_string_R1);
	I_ArrayProperty(const std::string &, FileName,
	                __C5_std_string_R1__getFileName__unsigned_int,
	                __void__setFileName__unsigned_int__C5_std_string_R1,
	                __unsigned_int__getNumFileNames,
	                0,
	                0,
	                0);
	I_ArrayProperty(double, FrameNumber,
	                __double__getFrameNumber__unsigned_int,
	                0,
	                __unsigned_int__getNumFrameNumbers,
	                0,
	                0,
	                0);
	I_SimpleProperty(int, FrameNumberOfLastTraversal,
	                 __int__getFrameNumberOfLastTraversal,
	                 __void__setFrameNumberOfLastTraversal__int);
	I_SimpleProperty(unsigned int, NumChildrenThatCannotBeExpired,
	                 0,
	                 __void__setNumChildrenThatCannotBeExpired__unsigned_int);
	I_ArrayProperty(float, PriorityOffset,
	                __float__getPriorityOffset__unsigned_int,
	                __void__setPriorityOffset__unsigned_int__float,
	                __unsigned_int__getNumPriorityOffsets,
	                0,
	                0,
	                0);
	I_ArrayProperty(float, PriorityScale,
	                __float__getPriorityScale__unsigned_int,
	                __void__setPriorityScale__unsigned_int__float,
	                __unsigned_int__getNumPriorityScales,
	                0,
	                0,
	                0);
	I_ArrayProperty(double, TimeStamp,
	                __double__getTimeStamp__unsigned_int,
	                __void__setTimeStamp__unsigned_int__double,
	                __unsigned_int__getNumTimeStamps,
	                0,
	                0,
	                0);
END_REFLECTOR

BEGIN_VALUE_REFLECTOR(osg::PagedLOD::PerRangeData)
	I_DeclaringFile("osg/PagedLOD");
	I_Constructor0(____PerRangeData,
	               "",
	               "");
	I_Constructor1(IN, const osg::PagedLOD::PerRangeData &, prd,
	               Properties::NON_EXPLICIT,
	               ____PerRangeData__C5_PerRangeData_R1,
	               "",
	               "");
	I_PublicMemberProperty(std::string, _filename);
	I_PublicMemberProperty(float, _priorityOffset);
	I_PublicMemberProperty(float, _priorityScale);
	I_PublicMemberProperty(double, _timeStamp);
	I_PublicMemberProperty(int, _frameNumber);
	I_PublicMemberProperty(int, _frameNumberOfLastReleaseGLObjects);
	I_PublicMemberProperty(osg::ref_ptr< osg::Referenced >, _databaseRequest);
END_REFLECTOR

STD_VECTOR_REFLECTOR(std::vector< osg::PagedLOD::PerRangeData >)

<commit_msg>Updated wrappers<commit_after>// ***************************************************************************
//
//   Generated automatically by genwrapper.
//   Please DO NOT EDIT this file!
//
// ***************************************************************************

#include <osgIntrospection/ReflectionMacros>
#include <osgIntrospection/TypedMethodInfo>
#include <osgIntrospection/StaticMethodInfo>
#include <osgIntrospection/Attributes>

#include <osg/CopyOp>
#include <osg/Group>
#include <osg/Node>
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/PagedLOD>
#include <osg/Referenced>

// Must undefine IN and OUT macros defined in Windows headers
#ifdef IN
#undef IN
#endif
#ifdef OUT
#undef OUT
#endif

TYPE_NAME_ALIAS(std::vector< osg::PagedLOD::PerRangeData >, osg::PagedLOD::PerRangeDataList)

BEGIN_OBJECT_REFLECTOR(osg::PagedLOD)
	I_DeclaringFile("osg/PagedLOD");
	I_BaseType(osg::LOD);
	I_Constructor0(____PagedLOD,
	               "",
	               "");
	I_ConstructorWithDefaults2(IN, const osg::PagedLOD &, x, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY,
	                           ____PagedLOD__C5_PagedLOD_R1__C5_CopyOp_R1,
	                           "Copy constructor using CopyOp to manage deep vs shallow copy. ",
	                           "");
	I_Method0(osg::Object *, cloneType,
	          Properties::VIRTUAL,
	          __osg_Object_P1__cloneType,
	          "clone an object of the same type as the node. ",
	          "");
	I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, copyop,
	          Properties::VIRTUAL,
	          __osg_Object_P1__clone__C5_osg_CopyOp_R1,
	          "return a clone of a node, with Object* return type. ",
	          "");
	I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj,
	          Properties::VIRTUAL,
	          __bool__isSameKindAs__C5_osg_Object_P1,
	          "return true if this and obj are of the same kind of object. ",
	          "");
	I_Method0(const char *, className,
	          Properties::VIRTUAL,
	          __C5_char_P1__className,
	          "return the name of the node's class type. ",
	          "");
	I_Method0(const char *, libraryName,
	          Properties::VIRTUAL,
	          __C5_char_P1__libraryName,
	          "return the name of the node's library. ",
	          "");
	I_Method1(void, accept, IN, osg::NodeVisitor &, nv,
	          Properties::VIRTUAL,
	          __void__accept__osg_NodeVisitor_R1,
	          "Visitor Pattern : calls the apply method of a NodeVisitor with this node's type. ",
	          "");
	I_Method1(void, traverse, IN, osg::NodeVisitor &, x,
	          Properties::VIRTUAL,
	          __void__traverse__NodeVisitor_R1,
	          "Traverse downwards : calls children's accept method with NodeVisitor. ",
	          "");
	I_Method1(bool, addChild, IN, osg::Node *, child,
	          Properties::VIRTUAL,
	          __bool__addChild__Node_P1,
	          "Add Node to Group. ",
	          "If node is not NULL and is not contained in Group then increment its reference count, add it to the child list and dirty the bounding sphere to force it to recompute on next getBound() and return true for success. Otherwise return false. Scene nodes can't be added as child nodes. ");
	I_Method3(bool, addChild, IN, osg::Node *, child, IN, float, min, IN, float, max,
	          Properties::VIRTUAL,
	          __bool__addChild__Node_P1__float__float,
	          "",
	          "");
	I_MethodWithDefaults6(bool, addChild, IN, osg::Node *, child, , IN, float, min, , IN, float, max, , IN, const std::string &, filename, , IN, float, priorityOffset, 0.0f, IN, float, priorityScale, 1.0f,
	                      Properties::VIRTUAL,
	                      __bool__addChild__Node_P1__float__float__C5_std_string_R1__float__float,
	                      "",
	                      "");
	I_MethodWithDefaults2(bool, removeChildren, IN, unsigned int, pos, , IN, unsigned int, numChildrenToRemove, 1,
	                      Properties::VIRTUAL,
	                      __bool__removeChildren__unsigned_int__unsigned_int,
	                      "Remove children from Group. ",
	                      "Note, must be override by subclasses of Group which add per child attributes. ");
	I_Method1(void, setDatabaseOptions, IN, osg::Referenced *, options,
	          Properties::NON_VIRTUAL,
	          __void__setDatabaseOptions__osg_Referenced_P1,
	          "Set the optional database osgDB::Options object to use when loaded children. ",
	          "");
	I_Method0(osg::Referenced *, getDatabaseOptions,
	          Properties::NON_VIRTUAL,
	          __osg_Referenced_P1__getDatabaseOptions,
	          "Get the optional database osgDB::Options object used when loaded children. ",
	          "");
	I_Method0(const osg::Referenced *, getDatabaseOptions,
	          Properties::NON_VIRTUAL,
	          __C5_osg_Referenced_P1__getDatabaseOptions,
	          "Get the optional database osgDB::Options object used when loaded children. ",
	          "");
	I_Method1(void, setDatabasePath, IN, const std::string &, path,
	          Properties::NON_VIRTUAL,
	          __void__setDatabasePath__C5_std_string_R1,
	          "Set the database path to prepend to children's filenames. ",
	          "");
	I_Method0(const std::string &, getDatabasePath,
	          Properties::NON_VIRTUAL,
	          __C5_std_string_R1__getDatabasePath,
	          "Get the database path used to prepend to children's filenames. ",
	          "");
	I_Method2(void, setFileName, IN, unsigned int, childNo, IN, const std::string &, filename,
	          Properties::NON_VIRTUAL,
	          __void__setFileName__unsigned_int__C5_std_string_R1,
	          "",
	          "");
	I_Method1(const std::string &, getFileName, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __C5_std_string_R1__getFileName__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumFileNames,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumFileNames,
	          "",
	          "");
	I_Method2(void, setPriorityOffset, IN, unsigned int, childNo, IN, float, priorityOffset,
	          Properties::NON_VIRTUAL,
	          __void__setPriorityOffset__unsigned_int__float,
	          "",
	          "");
	I_Method1(float, getPriorityOffset, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __float__getPriorityOffset__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumPriorityOffsets,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumPriorityOffsets,
	          "",
	          "");
	I_Method2(void, setPriorityScale, IN, unsigned int, childNo, IN, float, priorityScale,
	          Properties::NON_VIRTUAL,
	          __void__setPriorityScale__unsigned_int__float,
	          "",
	          "");
	I_Method1(float, getPriorityScale, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __float__getPriorityScale__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumPriorityScales,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumPriorityScales,
	          "",
	          "");
	I_Method2(void, setTimeStamp, IN, unsigned int, childNo, IN, double, timeStamp,
	          Properties::NON_VIRTUAL,
	          __void__setTimeStamp__unsigned_int__double,
	          "",
	          "");
	I_Method1(double, getTimeStamp, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __double__getTimeStamp__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumTimeStamps,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumTimeStamps,
	          "",
	          "");
	I_Method2(void, setFrameNumber, IN, unsigned int, childNo, IN, int, frameNumber,
	          Properties::NON_VIRTUAL,
	          __void__setFrameNumber__unsigned_int__int,
	          "",
	          "");
	I_Method1(double, getFrameNumber, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __double__getFrameNumber__unsigned_int,
	          "",
	          "");
	I_Method0(unsigned int, getNumFrameNumbers,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumFrameNumbers,
	          "",
	          "");
	I_Method1(osg::ref_ptr< osg::Referenced > &, getDatabaseRequest, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __osg_ref_ptrT1_osg_Referenced__R1__getDatabaseRequest__unsigned_int,
	          "Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests being carried on behalf of the DatabasePager. ",
	          "Note, in normal OSG usage you should not set this value yourself, as this will be managed by the osgDB::DatabasePager. ");
	I_Method1(const osg::ref_ptr< osg::Referenced > &, getDatabaseRequest, IN, unsigned int, childNo,
	          Properties::NON_VIRTUAL,
	          __C5_osg_ref_ptrT1_osg_Referenced__R1__getDatabaseRequest__unsigned_int,
	          "Return the const DatabaseRequest object. ",
	          "");
	I_Method1(void, setFrameNumberOfLastTraversal, IN, int, frameNumber,
	          Properties::NON_VIRTUAL,
	          __void__setFrameNumberOfLastTraversal__int,
	          "Set the frame number of the last time that this PageLOD node was traversed. ",
	          "Note, this frame number is automatically set by the traverse() method for all traversals (update, cull etc.). ");
	I_Method0(int, getFrameNumberOfLastTraversal,
	          Properties::NON_VIRTUAL,
	          __int__getFrameNumberOfLastTraversal,
	          "Get the frame number of the last time that this PageLOD node was traversed. ",
	          "");
	I_Method1(void, setNumChildrenThatCannotBeExpired, IN, unsigned int, num,
	          Properties::NON_VIRTUAL,
	          __void__setNumChildrenThatCannotBeExpired__unsigned_int,
	          "Set the number of children that the PagedLOD must keep around, even if they are older than their expiry time. ",
	          "");
	I_Method0(unsigned int, getNumChildrenThatCannotBeExpired,
	          Properties::NON_VIRTUAL,
	          __unsigned_int__getNumChildrenThatCannotBeExpired,
	          "Get the number of children that the PagedLOD must keep around, even if they are older than their expiry time. ",
	          "");
	I_Method1(void, setDisableExternalChildrenPaging, IN, bool, flag,
	          Properties::NON_VIRTUAL,
	          __void__setDisableExternalChildrenPaging__bool,
	          "Set wether you want to disable the paging in of external nodes. ",
	          "");
	I_Method0(bool, getDisableExternalChildrenPaging,
	          Properties::NON_VIRTUAL,
	          __bool__getDisableExternalChildrenPaging,
	          "",
	          "");
	I_Method3(bool, removeExpiredChildren, IN, double, expiryTime, IN, int, expiryFrame, IN, osg::NodeList &, removedChildren,
	          Properties::VIRTUAL,
	          __bool__removeExpiredChildren__double__int__NodeList_R1,
	          "Remove the children from the PagedLOD which haven't been visited since specified expiry time and expiry frame number. ",
	          "The removed children are added to the removeChildren list passed into the method, this allows the children to be deleted later at the caller's discretion. Return true if children are removed, false otherwise. ");
	I_Method2(bool, releaseGLObjectsOnExpiredChildren, IN, double, releaseTime, IN, int, releaseFrame,
	          Properties::VIRTUAL,
	          __bool__releaseGLObjectsOnExpiredChildren__double__int,
	          "Release the GL Objects of the children from the PagedLOD which haven't been visited since specified expiry time and expiry frame number. ",
	          "Return true if any children have release called upon them, false otherwise. ");
	I_ProtectedMethod1(void, expandPerRangeDataTo, IN, unsigned int, pos,
	                   Properties::NON_VIRTUAL,
	                   Properties::NON_CONST,
	                   __void__expandPerRangeDataTo__unsigned_int,
	                   "",
	                   "");
	I_SimpleProperty(osg::Referenced *, DatabaseOptions,
	                 __osg_Referenced_P1__getDatabaseOptions,
	                 __void__setDatabaseOptions__osg_Referenced_P1);
	I_SimpleProperty(const std::string &, DatabasePath,
	                 __C5_std_string_R1__getDatabasePath,
	                 __void__setDatabasePath__C5_std_string_R1);
	I_SimpleProperty(bool, DisableExternalChildrenPaging,
	                 __bool__getDisableExternalChildrenPaging,
	                 __void__setDisableExternalChildrenPaging__bool);
	I_ArrayProperty(const std::string &, FileName,
	                __C5_std_string_R1__getFileName__unsigned_int,
	                __void__setFileName__unsigned_int__C5_std_string_R1,
	                __unsigned_int__getNumFileNames,
	                0,
	                0,
	                0);
	I_ArrayProperty(double, FrameNumber,
	                __double__getFrameNumber__unsigned_int,
	                0,
	                __unsigned_int__getNumFrameNumbers,
	                0,
	                0,
	                0);
	I_SimpleProperty(int, FrameNumberOfLastTraversal,
	                 __int__getFrameNumberOfLastTraversal,
	                 __void__setFrameNumberOfLastTraversal__int);
	I_SimpleProperty(unsigned int, NumChildrenThatCannotBeExpired,
	                 0,
	                 __void__setNumChildrenThatCannotBeExpired__unsigned_int);
	I_ArrayProperty(float, PriorityOffset,
	                __float__getPriorityOffset__unsigned_int,
	                __void__setPriorityOffset__unsigned_int__float,
	                __unsigned_int__getNumPriorityOffsets,
	                0,
	                0,
	                0);
	I_ArrayProperty(float, PriorityScale,
	                __float__getPriorityScale__unsigned_int,
	                __void__setPriorityScale__unsigned_int__float,
	                __unsigned_int__getNumPriorityScales,
	                0,
	                0,
	                0);
	I_ArrayProperty(double, TimeStamp,
	                __double__getTimeStamp__unsigned_int,
	                __void__setTimeStamp__unsigned_int__double,
	                __unsigned_int__getNumTimeStamps,
	                0,
	                0,
	                0);
END_REFLECTOR

BEGIN_VALUE_REFLECTOR(osg::PagedLOD::PerRangeData)
	I_DeclaringFile("osg/PagedLOD");
	I_Constructor0(____PerRangeData,
	               "",
	               "");
	I_Constructor1(IN, const osg::PagedLOD::PerRangeData &, prd,
	               Properties::NON_EXPLICIT,
	               ____PerRangeData__C5_PerRangeData_R1,
	               "",
	               "");
	I_PublicMemberProperty(std::string, _filename);
	I_PublicMemberProperty(float, _priorityOffset);
	I_PublicMemberProperty(float, _priorityScale);
	I_PublicMemberProperty(double, _timeStamp);
	I_PublicMemberProperty(int, _frameNumber);
	I_PublicMemberProperty(int, _frameNumberOfLastReleaseGLObjects);
	I_PublicMemberProperty(osg::ref_ptr< osg::Referenced >, _databaseRequest);
END_REFLECTOR

STD_VECTOR_REFLECTOR(std::vector< osg::PagedLOD::PerRangeData >)

<|endoftext|>


<commit_before><commit_msg>legion: fix a tracing bug<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS changefileheader (1.3.492); FILE MERGED 2008/03/31 17:19:59 rt 1.3.492.1: #i87441# Change license header to LPGL v3.<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS aw024 (1.36.84); FILE MERGED 2006/09/21 23:45:14 aw 1.36.84.6: RESYNC: (1.40-1.41); FILE MERGED 2006/08/03 16:39:09 aw 1.36.84.5: RESYNC: (1.38-1.40); FILE MERGED 2006/01/26 20:18:48 aw 1.36.84.4: RESYNC: (1.37-1.38); FILE MERGED 2005/09/17 14:09:21 aw 1.36.84.3: RESYNC: (1.36-1.37); FILE MERGED 2005/05/26 11:24:44 aw 1.36.84.2: #i39531# 2005/05/19 12:11:39 aw 1.36.84.1: #i39529#<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS impress20ea (1.32.26); FILE MERGED 2004/10/14 13:18:22 af 1.32.26.4: RESYNC: (1.32-1.33); FILE MERGED 2004/10/05 10:59:56 af 1.32.26.3: #i34868# Calling CreateTitleAndLayout() for new master pages to create placeholder shapes. 2004/09/16 16:06:33 af 1.32.26.2: #i34011# Added handling of SID_INSERT_MASTER_PAGE slot. 2004/09/15 08:03:25 af 1.32.26.1: #i34011# Added the new master view slots.<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS impress100 (1.80.68); FILE MERGED 2006/07/31 14:23:46 cl 1.80.68.1: #i63682# do not create undo actions for copy operation<commit_after><|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/plang/BufferedInvocation.hpp>

#ifdef PDAL_COMPILER_MSVC
#  pragma warning(disable: 4127)  // conditional expression is constant
#  pragma warning(disable: 4505)  // unreferenced local function has been removed
#endif

using namespace pdal;

namespace pdal
{
namespace plang
{

BufferedInvocation::BufferedInvocation(const Script& script)
    : Invocation(script)
{
    return;
}

void BufferedInvocation::begin(PointBuffer& buffer)
{
    PointContext ctx = buffer.m_context;
    Dimension::IdList const& dims = ctx.dims();

    for (auto di = dims.begin(); di != dims.end(); ++di)
    {
        Dimension::Id::Enum d = *di;
        Dimension::Detail *dd = ctx.dimDetail(d);
        void *data = malloc(dd->size() * buffer.size());
        m_buffers.push_back(data);  // Hold pointer for deallocation
        char *p = (char *)data;
        for (PointId idx = 0; idx < buffer.size(); ++idx)
        {
            buffer.getFieldInternal(d, idx, (void *)p);
            p += dd->size();
        }
        std::string name = Dimension::name(d);
        insertArgument(name, (uint8_t *)data, dd->type(), buffer.size());
    }
}

void BufferedInvocation::end(PointBuffer& buffer)
{
    // for each entry in the script's outs dictionary,
    // look up that entry's name in the schema and then
    // copy the data into the right dimension spot in the
    // buffer

    std::vector<std::string> names;
    getOutputNames(names);

    // const Schema& schema = buffer.getSchema();

    for (size_t i = 0; i < names.size(); i++)
    {
        PointContext ctx = buffer.m_context;
        Dimension::Id::Enum d = ctx.findDim(names[i]);
        if (d == Dimension::Id::Unknown)
            continue;

        Dimension::Detail *dd = ctx.dimDetail(d);
        std::string name = Dimension::name(d);
        assert(name == names[i]);
        assert(hasOutputVariable(name));

        size_t size = dd->size();
        void *data = extractResult(name, dd->type());
        char *p = (char *)data;
        for (PointId idx = 0; idx < buffer.size(); ++idx)
        {
            buffer.setField(d, dd->type(), idx, (void *)p);
            p += size;
        }
    }
    for (auto bi = m_buffers.begin(); bi != m_buffers.end(); ++bi)
        free(*bi);
    m_buffers.clear();
}

} //namespace plang
} //namespace pdal

<commit_msg>We were using the default dimension name rather than the actual dimension name for filtering. Custom dimensions ended up being ''<commit_after>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/plang/BufferedInvocation.hpp>

#ifdef PDAL_COMPILER_MSVC
#  pragma warning(disable: 4127)  // conditional expression is constant
#  pragma warning(disable: 4505)  // unreferenced local function has been removed
#endif

using namespace pdal;

namespace pdal
{
namespace plang
{

BufferedInvocation::BufferedInvocation(const Script& script)
    : Invocation(script)
{
    return;
}

void BufferedInvocation::begin(PointBuffer& buffer)
{
    PointContext ctx = buffer.m_context;
    Dimension::IdList const& dims = ctx.dims();

    for (auto di = dims.begin(); di != dims.end(); ++di)
    {
        Dimension::Id::Enum d = *di;
        Dimension::Detail *dd = ctx.dimDetail(d);
        void *data = malloc(dd->size() * buffer.size());
        m_buffers.push_back(data);  // Hold pointer for deallocation
        char *p = (char *)data;
        for (PointId idx = 0; idx < buffer.size(); ++idx)
        {
            buffer.getFieldInternal(d, idx, (void *)p);
            p += dd->size();
        }
        std::string name = ctx.dimName(*di);
        insertArgument(name, (uint8_t *)data, dd->type(), buffer.size());
    }
}

void BufferedInvocation::end(PointBuffer& buffer)
{
    // for each entry in the script's outs dictionary,
    // look up that entry's name in the schema and then
    // copy the data into the right dimension spot in the
    // buffer

    std::vector<std::string> names;
    getOutputNames(names);

    // const Schema& schema = buffer.getSchema();

    for (size_t i = 0; i < names.size(); i++)
    {
        PointContext ctx = buffer.m_context;
        Dimension::Id::Enum d = ctx.findDim(names[i]);
        if (d == Dimension::Id::Unknown)
            continue;

        Dimension::Detail *dd = ctx.dimDetail(d);
        std::string name = Dimension::name(d);
        assert(name == names[i]);
        assert(hasOutputVariable(name));

        size_t size = dd->size();
        void *data = extractResult(name, dd->type());
        char *p = (char *)data;
        for (PointId idx = 0; idx < buffer.size(); ++idx)
        {
            buffer.setField(d, dd->type(), idx, (void *)p);
            p += size;
        }
    }
    for (auto bi = m_buffers.begin(); bi != m_buffers.end(); ++bi)
        free(*bi);
    m_buffers.clear();
}

} //namespace plang
} //namespace pdal

<|endoftext|>


<commit_before>/**
 * The Seeks proxy and plugin framework are part of the SEEKS project.
 * Copyright (C) 2009 Emmanuel Benazera, juban@free.fr
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 */

#include "sweeper.h"
#include "mem_utils.h"
#include "seeks_proxy.h"
#include "miscutil.h"
#include "errlog.h"

#include <iostream>

namespace sp
{
  /*- sweepable. -*/
  sweepable::sweepable()
  {
  }

  sweepable::~sweepable()
  {
  }

  /*- sweeper. -*/

  sp_mutex_t sweeper::_mem_dust_mutex;

  void sweeper::register_sweepable(sweepable *spable)
  {
    mutex_lock(&sweeper::_mem_dust_mutex);
    seeks_proxy::_memory_dust.push_back(spable);
    mutex_unlock(&sweeper::_mem_dust_mutex);
  }

  void sweeper::unregister_sweepable(sweepable *spable)
  {
    mutex_lock(&sweeper::_mem_dust_mutex);
    std::vector<sweepable*>::iterator vit
    = seeks_proxy::_memory_dust.begin();
    while (vit!=seeks_proxy::_memory_dust.end())
      {
        if ((*vit) == spable)
          {
            seeks_proxy::_memory_dust.erase(vit);
            mutex_unlock(&sweeper::_mem_dust_mutex);
            return;
          }
        ++vit;
      }
    mutex_unlock(&sweeper::_mem_dust_mutex);
  }

  /*********************************************************************
   * Function    :  sweep
   *
   * Description :  Basically a mark and sweep garbage collector, it is run
   *                (by the parent thread) every once in a while to reclaim
   *                memory.
   *
   * It uses a mark and sweep strategy:
   *   1) mark all files as inactive
   *
   *   2) check with each client:
   *       if it is active,   mark its files as active
   *       if it is inactive, free its resources
   *
   *   3) free the resources.
   *
   * Returns     :  The number of threads that are still active.
   *
   *********************************************************************/
  unsigned int sweeper::sweep()
  {
    client_state *csp, *last_active;
    unsigned int active_threads = 0;

    last_active = &seeks_proxy::_clients;
    csp = seeks_proxy::_clients._next;

    while (NULL != csp)
      {
        if (csp->_flags & CSP_FLAG_ACTIVE)
          {
            active_threads++;

            last_active = csp;
            csp = csp->_next;
          }
        else
          /*
           * This client is not active. Free its resources.
           */
          //TODO: should go into client_state destructor.
          {
            last_active->_next = csp->_next;

            freez(csp->_ip_addr_str);
            freez(csp->_iob._buf);
            //freez(csp->_error_message);

            if (csp->_action._flags & ACTION_FORWARD_OVERRIDE &&
                NULL != csp->_fwd)
              {
                delete csp->_fwd;
              }

            /* miscutil::list_remove_all(&csp->_headers);
             miscutil::list_remove_all(&csp->_tags); */

#ifdef FEATURE_STATISTICS
            seeks_proxy::_urls_read++;
            if (csp->_flags & CSP_FLAG_REJECTED)
              {
                seeks_proxy::_urls_rejected++;
              }
#endif /* def FEATURE_STATISTICS */

            delete csp;
            csp = last_active->_next;
          }
      }

    /* sweeps other memory dust grains, as necessary. */

    //debug
    /* std::cerr << "[Debug]:sweeper: cleaning memory dust: "
     << seeks_proxy::_memory_dust.size() << " remaining items\n"; */
    //debug

    mutex_lock(&sweeper::_mem_dust_mutex);
    std::vector<sweepable*>::iterator vit = seeks_proxy::_memory_dust.begin();
    while (vit!=seeks_proxy::_memory_dust.end())
      {
        sweepable *spable = (*vit);
        if (spable->sweep_me())
          {
            delete spable;
            vit = seeks_proxy::_memory_dust.erase(vit);
          }
        else ++vit;
      }
    mutex_unlock(&sweeper::_mem_dust_mutex);

#if defined(PROTOBUF) && defined(TC)
    // user_db sweep.
    seeks_proxy::_user_db->sweep_db();
#endif

    return active_threads;
  }

  unsigned int sweeper::sweep_all_memory_dust()
  {
    unsigned int nm = seeks_proxy::_memory_dust.size();
    std::vector<sweepable*>::iterator vit = seeks_proxy::_memory_dust.begin();
    while (vit!=seeks_proxy::_memory_dust.end())
      {
        sweepable *spable = (*vit);
        delete spable;
        vit = seeks_proxy::_memory_dust.erase(vit);
      }
    errlog::log_error(LOG_LEVEL_INFO, "sweep_all: destroyed %u elements",nm);
    return nm;
  }

  unsigned int sweeper::sweep_all_csps()
  {
    client_state *csp, *last_active;
    unsigned int active_threads = 0;

    last_active = &seeks_proxy::_clients;
    csp = seeks_proxy::_clients._next;

    while (NULL != csp)
      {
        active_threads++;

        /*
         * This client is not active. Free its resources.
         */
        //TODO: should go into client_state destructor.
        {
          last_active->_next = csp->_next;
          freez(csp->_ip_addr_str);
          freez(csp->_iob._buf);

          if (csp->_action._flags & ACTION_FORWARD_OVERRIDE &&
              NULL != csp->_fwd)
            {
              delete csp->_fwd;
            }
          delete csp;
          csp = last_active->_next;
        }
      }
    return active_threads;
  }

  unsigned int sweeper::sweep_all()
  {
    return sweeper::sweep_all_csps() + sweeper::sweep_all_memory_dust();
  }

} /* end of namespace. */
<commit_msg>sweeper commented code cleanup<commit_after>/**
 * The Seeks proxy and plugin framework are part of the SEEKS project.
 * Copyright (C) 2009 Emmanuel Benazera, juban@free.fr
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 */

#include "sweeper.h"
#include "mem_utils.h"
#include "seeks_proxy.h"
#include "miscutil.h"
#include "errlog.h"

#include <iostream>

namespace sp
{
  /*- sweepable. -*/
  sweepable::sweepable()
  {
  }

  sweepable::~sweepable()
  {
  }

  /*- sweeper. -*/

  sp_mutex_t sweeper::_mem_dust_mutex;

  void sweeper::register_sweepable(sweepable *spable)
  {
    mutex_lock(&sweeper::_mem_dust_mutex);
    seeks_proxy::_memory_dust.push_back(spable);
    mutex_unlock(&sweeper::_mem_dust_mutex);
  }

  void sweeper::unregister_sweepable(sweepable *spable)
  {
    mutex_lock(&sweeper::_mem_dust_mutex);
    std::vector<sweepable*>::iterator vit
    = seeks_proxy::_memory_dust.begin();
    while (vit!=seeks_proxy::_memory_dust.end())
      {
        if ((*vit) == spable)
          {
            seeks_proxy::_memory_dust.erase(vit);
            mutex_unlock(&sweeper::_mem_dust_mutex);
            return;
          }
        ++vit;
      }
    mutex_unlock(&sweeper::_mem_dust_mutex);
  }

  /*********************************************************************
   * Function    :  sweep
   *
   * Description :  Basically a mark and sweep garbage collector, it is run
   *                (by the parent thread) every once in a while to reclaim
   *                memory.
   *
   * It uses a mark and sweep strategy:
   *   1) mark all files as inactive
   *
   *   2) check with each client:
   *       if it is active,   mark its files as active
   *       if it is inactive, free its resources
   *
   *   3) free the resources.
   *
   * Returns     :  The number of threads that are still active.
   *
   *********************************************************************/
  unsigned int sweeper::sweep()
  {
    client_state *csp, *last_active;
    unsigned int active_threads = 0;

    last_active = &seeks_proxy::_clients;
    csp = seeks_proxy::_clients._next;

    while (NULL != csp)
      {
        if (csp->_flags & CSP_FLAG_ACTIVE)
          {
            active_threads++;

            last_active = csp;
            csp = csp->_next;
          }
        else
          /*
           * This client is not active. Free its resources.
           */
          //TODO: should go into client_state destructor.
          {
            last_active->_next = csp->_next;

            freez(csp->_ip_addr_str);
            freez(csp->_iob._buf);

            if (csp->_action._flags & ACTION_FORWARD_OVERRIDE &&
                NULL != csp->_fwd)
              {
                delete csp->_fwd;
              }

#ifdef FEATURE_STATISTICS
            seeks_proxy::_urls_read++;
            if (csp->_flags & CSP_FLAG_REJECTED)
              {
                seeks_proxy::_urls_rejected++;
              }
#endif /* def FEATURE_STATISTICS */

            delete csp;
            csp = last_active->_next;
          }
      }

    /* sweeps other memory dust grains, as necessary. */

    //debug
    /* std::cerr << "[Debug]:sweeper: cleaning memory dust: "
     << seeks_proxy::_memory_dust.size() << " remaining items\n"; */
    //debug

    mutex_lock(&sweeper::_mem_dust_mutex);
    std::vector<sweepable*>::iterator vit = seeks_proxy::_memory_dust.begin();
    while (vit!=seeks_proxy::_memory_dust.end())
      {
        sweepable *spable = (*vit);
        if (spable->sweep_me())
          {
            delete spable;
            vit = seeks_proxy::_memory_dust.erase(vit);
          }
        else ++vit;
      }
    mutex_unlock(&sweeper::_mem_dust_mutex);

#if defined(PROTOBUF) && defined(TC)
    // user_db sweep.
    seeks_proxy::_user_db->sweep_db();
#endif

    return active_threads;
  }

  unsigned int sweeper::sweep_all_memory_dust()
  {
    unsigned int nm = seeks_proxy::_memory_dust.size();
    std::vector<sweepable*>::iterator vit = seeks_proxy::_memory_dust.begin();
    while (vit!=seeks_proxy::_memory_dust.end())
      {
        sweepable *spable = (*vit);
        delete spable;
        vit = seeks_proxy::_memory_dust.erase(vit);
      }
    errlog::log_error(LOG_LEVEL_INFO, "sweep_all: destroyed %u elements",nm);
    return nm;
  }

  unsigned int sweeper::sweep_all_csps()
  {
    client_state *csp, *last_active;
    unsigned int active_threads = 0;

    last_active = &seeks_proxy::_clients;
    csp = seeks_proxy::_clients._next;

    while (NULL != csp)
      {
        active_threads++;

        /*
         * This client is not active. Free its resources.
         */
        //TODO: should go into client_state destructor.
        {
          last_active->_next = csp->_next;
          freez(csp->_ip_addr_str);
          freez(csp->_iob._buf);

          if (csp->_action._flags & ACTION_FORWARD_OVERRIDE &&
              NULL != csp->_fwd)
            {
              delete csp->_fwd;
            }
          delete csp;
          csp = last_active->_next;
        }
      }
    return active_threads;
  }

  unsigned int sweeper::sweep_all()
  {
    return sweeper::sweep_all_csps() + sweeper::sweep_all_memory_dust();
  }

} /* end of namespace. */
<|endoftext|>


<commit_before>#include "wrap_body.hpp"
#include "wrap_exception.hpp"
#include "wrap_fixture.hpp"
#include "wrap_shape.hpp"
#include "wrap_vec_2.hpp"
#include "wrap_vertex_array.hpp"
#include "wrap_world.hpp"

#include <boost/python.hpp>
#include <Box2D/Common/b2Settings.h>

using namespace boost::python;

BOOST_PYTHON_MODULE(pysics)
{
    using namespace pysics;

    wrap_exception();
    wrap_vec_2();
    wrap_vertex_array();
    wrap_body_type();
    wrap_world();
    wrap_body();
    wrap_fixture();
    wrap_mass_data();
    wrap_shape_type();
    wrap_shape();
    wrap_circle_shape();
    wrap_edge_shape();
    wrap_polygon_shape();
    wrap_loop_shape();
}
<commit_msg>cleaned up pysics.cpp<commit_after>#include "wrap_body.hpp"
#include "wrap_exception.hpp"
#include "wrap_fixture.hpp"
#include "wrap_shape.hpp"
#include "wrap_vec_2.hpp"
#include "wrap_vertex_array.hpp"
#include "wrap_world.hpp"

#include <boost/python.hpp>

using namespace pysics;
using namespace boost::python;

BOOST_PYTHON_MODULE(pysics)
{
    wrap_exception();
    wrap_vec_2();
    wrap_vertex_array();
    wrap_body_type();
    wrap_world();
    wrap_body();
    wrap_fixture();
    wrap_mass_data();
    wrap_shape_type();
    wrap_shape();
    wrap_circle_shape();
    wrap_edge_shape();
    wrap_polygon_shape();
    wrap_loop_shape();
}
<|endoftext|>


<commit_before><commit_msg>Allow temporary FP single symbols to be loaded and stored when their location is greater than 0x400.<commit_after><|endoftext|>


<commit_before><commit_msg>DO NOT MERGE Fix extra texture creation in GrResourceProvider::createTexture() with SRGB data.<commit_after><|endoftext|>


<commit_before><commit_msg>added a method which allows to project a given MLS into a TSDF map<commit_after><|endoftext|>


<commit_before>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <wincodec.h>
#include "SkAutoCoInitialize.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkIStream.h"
#include "SkMovie.h"
#include "SkStream.h"
#include "SkTScopedComPtr.h"
#include "SkUnPreMultiply.h"

class SkImageDecoder_WIC : public SkImageDecoder {
protected:
    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
};

bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
    //Initialize COM.
    SkAutoCoInitialize scopedCo;
    if (!scopedCo.succeeded()) {
        return false;
    }

    HRESULT hr = S_OK;

    //Create Windows Imaging Component ImagingFactory.
    SkTScopedComPtr<IWICImagingFactory> piImagingFactory;
    if (SUCCEEDED(hr)) {
        hr = CoCreateInstance(
            CLSID_WICImagingFactory
            , NULL
            , CLSCTX_INPROC_SERVER
            , IID_PPV_ARGS(&piImagingFactory)
        );
    }

    //Convert SkStream to IStream.
    SkTScopedComPtr<IStream> piStream;
    if (SUCCEEDED(hr)) {
        hr = SkIStream::CreateFromSkStream(stream, false, &piStream);
    }

    //Make sure we're at the beginning of the stream.
    if (SUCCEEDED(hr)) {
        LARGE_INTEGER liBeginning = { 0 };
        hr = piStream->Seek(liBeginning, STREAM_SEEK_SET, NULL);
    }

    //Create the decoder from the stream content.
    SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder;
    if (SUCCEEDED(hr)) {
        hr = piImagingFactory->CreateDecoderFromStream(
            piStream.get()                    //Image to be decoded
            , NULL                            //No particular vendor
            , WICDecodeMetadataCacheOnDemand  //Cache metadata when needed
            , &piBitmapDecoder                //Pointer to the decoder
        );
    }

    //Get the first frame from the decoder.
    SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode;
    if (SUCCEEDED(hr)) {
        hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode);
    }

    //Get the BitmapSource interface of the frame.
    SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal;
    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameDecode->QueryInterface(
            IID_PPV_ARGS(&piBitmapSourceOriginal)
        );
    }

    //Get the size of the bitmap.
    UINT width;
    UINT height;
    if (SUCCEEDED(hr)) {
        hr = piBitmapSourceOriginal->GetSize(&width, &height);
    }

    //Exit early if we're only looking for the bitmap bounds.
    if (SUCCEEDED(hr)) {
        bm->setConfig(SkBitmap::kARGB_8888_Config, width, height);
        if (SkImageDecoder::kDecodeBounds_Mode == mode) {
            return true;
        }
        if (!this->allocPixelRef(bm, NULL)) {
            return false;
        }
    }

    //Create a format converter.
    SkTScopedComPtr<IWICFormatConverter> piFormatConverter;
    if (SUCCEEDED(hr)) {
        hr = piImagingFactory->CreateFormatConverter(&piFormatConverter);
    }

    if (SUCCEEDED(hr)) {
        hr = piFormatConverter->Initialize(
            piBitmapSourceOriginal.get()      //Input bitmap to convert
            , GUID_WICPixelFormat32bppPBGRA   //Destination pixel format
            , WICBitmapDitherTypeNone         //Specified dither patterm
            , NULL                            //Specify a particular palette
            , 0.f                             //Alpha threshold
            , WICBitmapPaletteTypeCustom      //Palette translation type
        );
    }

    //Get the BitmapSource interface of the format converter.
    SkTScopedComPtr<IWICBitmapSource> piBitmapSourceConverted;
    if (SUCCEEDED(hr)) {
        hr = piFormatConverter->QueryInterface(
            IID_PPV_ARGS(&piBitmapSourceConverted)
        );
    }

    //Copy the pixels into the bitmap.
    if (SUCCEEDED(hr)) {
        SkAutoLockPixels alp(*bm);
        bm->eraseColor(SK_ColorTRANSPARENT);
        const int stride = bm->rowBytes();
        hr = piBitmapSourceConverted->CopyPixels(
            NULL,                             //Get all the pixels
            stride,
            stride * height,
            reinterpret_cast<BYTE *>(bm->getPixels())
        );

        // Note: we don't need to premultiply here since we specified PBGRA
        bm->computeAndSetOpaquePredicate();
    }

    return SUCCEEDED(hr);
}

/////////////////////////////////////////////////////////////////////////

SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
    return SkNEW(SkImageDecoder_WIC);
}

/////////////////////////////////////////////////////////////////////////

SkMovie* SkMovie::DecodeStream(SkStream* stream) {
    return NULL;
}

/////////////////////////////////////////////////////////////////////////

class SkImageEncoder_WIC : public SkImageEncoder {
public:
    SkImageEncoder_WIC(Type t) : fType(t) {}

protected:
    virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality);

private:
    Type fType;
};

bool SkImageEncoder_WIC::onEncode(SkWStream* stream
                                , const SkBitmap& bitmapOrig
                                , int quality)
{
    GUID type;
    switch (fType) {
        case kJPEG_Type:
            type = GUID_ContainerFormatJpeg;
            break;
        case kPNG_Type:
            type = GUID_ContainerFormatPng;
            break;
        default:
            return false;
    }

    //Convert to 8888 if needed.
    const SkBitmap* bitmap;
    SkBitmap bitmapCopy;
    if (SkBitmap::kARGB_8888_Config == bitmapOrig.config() && bitmapOrig.isOpaque()) {
        bitmap = &bitmapOrig;
    } else {
        if (!bitmapOrig.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config)) {
            return false;
        }
        bitmap = &bitmapCopy;
    }

    // We cannot use PBGRA so we need to unpremultiply ourselves
    if (!bitmap->isOpaque()) {
        SkAutoLockPixels alp(*bitmap);

        uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap->getPixels());
        for (int y = 0; y < bitmap->height(); ++y) {
            for (int x = 0; x < bitmap->width(); ++x) {
                uint8_t* bytes = pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel();

                SkPMColor* src = reinterpret_cast<SkPMColor*>(bytes);
                SkColor* dst = reinterpret_cast<SkColor*>(bytes);

                *dst = SkUnPreMultiply::PMColorToColor(*src);
            }
        }
    }

    //Initialize COM.
    SkAutoCoInitialize scopedCo;
    if (!scopedCo.succeeded()) {
        return false;
    }

    HRESULT hr = S_OK;

    //Create Windows Imaging Component ImagingFactory.
    SkTScopedComPtr<IWICImagingFactory> piImagingFactory;
    if (SUCCEEDED(hr)) {
        hr = CoCreateInstance(
            CLSID_WICImagingFactory
            , NULL
            , CLSCTX_INPROC_SERVER
            , IID_PPV_ARGS(&piImagingFactory)
        );
    }

    //Convert the SkWStream to an IStream.
    SkTScopedComPtr<IStream> piStream;
    if (SUCCEEDED(hr)) {
        hr = SkWIStream::CreateFromSkWStream(stream, &piStream);
    }

    //Create an encode of the appropriate type.
    SkTScopedComPtr<IWICBitmapEncoder> piEncoder;
    if (SUCCEEDED(hr)) {
        hr = piImagingFactory->CreateEncoder(type, NULL, &piEncoder);
    }

    if (SUCCEEDED(hr)) {
        hr = piEncoder->Initialize(piStream.get(), WICBitmapEncoderNoCache);
    }

    //Create a the frame.
    SkTScopedComPtr<IWICBitmapFrameEncode> piBitmapFrameEncode;
    SkTScopedComPtr<IPropertyBag2> piPropertybag;
    if (SUCCEEDED(hr)) {
        hr = piEncoder->CreateNewFrame(&piBitmapFrameEncode, &piPropertybag);
    }

    if (SUCCEEDED(hr)) {
        PROPBAG2 name = { 0 };
        name.dwType = PROPBAG2_TYPE_DATA;
        name.vt = VT_R4;
        name.pstrName = L"ImageQuality";

        VARIANT value;
        VariantInit(&value);
        value.vt = VT_R4;
        value.fltVal = (FLOAT)(quality / 100.0);

        //Ignore result code.
        //  This returns E_FAIL if the named property is not in the bag.
        //TODO(bungeman) enumerate the properties,
        //  write and set hr iff property exists.
        piPropertybag->Write(1, &name, &value);
    }
    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameEncode->Initialize(piPropertybag.get());
    }

    //Set the size of the frame.
    const UINT width = bitmap->width();
    const UINT height = bitmap->height();
    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameEncode->SetSize(width, height);
    }

    //Set the pixel format of the frame.
    const WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA;
    WICPixelFormatGUID formatGUID = formatDesired;
    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameEncode->SetPixelFormat(&formatGUID);
    }
    if (SUCCEEDED(hr)) {
        //Be sure the image format is the one requested.
        hr = IsEqualGUID(formatGUID, formatDesired) ? S_OK : E_FAIL;
    }

    //Write the pixels into the frame.
    if (SUCCEEDED(hr)) {
        SkAutoLockPixels alp(*bitmap);
        hr = piBitmapFrameEncode->WritePixels(
            height
            , bitmap->rowBytes()
            , bitmap->rowBytes()*height
            , reinterpret_cast<BYTE*>(bitmap->getPixels()));
    }

    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameEncode->Commit();
    }

    if (SUCCEEDED(hr)) {
        hr = piEncoder->Commit();
    }

    return SUCCEEDED(hr);
}

SkImageEncoder* SkImageEncoder::Create(Type t) {
    switch (t) {
        case kJPEG_Type:
        case kPNG_Type:
            break;
        default:
            return NULL;
    }
    return SkNEW_ARGS(SkImageEncoder_WIC, (t));
}

<commit_msg>SkImageDecoder_WIC should work on Win7 with Win8 SDK. https://codereview.appspot.com/7099044/<commit_after>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <wincodec.h>
#include "SkAutoCoInitialize.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkIStream.h"
#include "SkMovie.h"
#include "SkStream.h"
#include "SkTScopedComPtr.h"
#include "SkUnPreMultiply.h"

//All Windows SDKs back to XPSP2 export the CLSID_WICImagingFactory symbol.
//In the Windows8 SDK the CLSID_WICImagingFactory symbol is still exported
//but CLSID_WICImagingFactory is then #defined to CLSID_WICImagingFactory2.
//Undo this #define if it has been done so that we link against the symbols
//we intended to link against on all SDKs.
#if defined(CLSID_WICImagingFactory)
#undef CLSID_WICImagingFactory
#endif

class SkImageDecoder_WIC : public SkImageDecoder {
protected:
    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
};

bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
    //Initialize COM.
    SkAutoCoInitialize scopedCo;
    if (!scopedCo.succeeded()) {
        return false;
    }

    HRESULT hr = S_OK;

    //Create Windows Imaging Component ImagingFactory.
    SkTScopedComPtr<IWICImagingFactory> piImagingFactory;
    if (SUCCEEDED(hr)) {
        hr = CoCreateInstance(
            CLSID_WICImagingFactory
            , NULL
            , CLSCTX_INPROC_SERVER
            , IID_PPV_ARGS(&piImagingFactory)
        );
    }

    //Convert SkStream to IStream.
    SkTScopedComPtr<IStream> piStream;
    if (SUCCEEDED(hr)) {
        hr = SkIStream::CreateFromSkStream(stream, false, &piStream);
    }

    //Make sure we're at the beginning of the stream.
    if (SUCCEEDED(hr)) {
        LARGE_INTEGER liBeginning = { 0 };
        hr = piStream->Seek(liBeginning, STREAM_SEEK_SET, NULL);
    }

    //Create the decoder from the stream content.
    SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder;
    if (SUCCEEDED(hr)) {
        hr = piImagingFactory->CreateDecoderFromStream(
            piStream.get()                    //Image to be decoded
            , NULL                            //No particular vendor
            , WICDecodeMetadataCacheOnDemand  //Cache metadata when needed
            , &piBitmapDecoder                //Pointer to the decoder
        );
    }

    //Get the first frame from the decoder.
    SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode;
    if (SUCCEEDED(hr)) {
        hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode);
    }

    //Get the BitmapSource interface of the frame.
    SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal;
    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameDecode->QueryInterface(
            IID_PPV_ARGS(&piBitmapSourceOriginal)
        );
    }

    //Get the size of the bitmap.
    UINT width;
    UINT height;
    if (SUCCEEDED(hr)) {
        hr = piBitmapSourceOriginal->GetSize(&width, &height);
    }

    //Exit early if we're only looking for the bitmap bounds.
    if (SUCCEEDED(hr)) {
        bm->setConfig(SkBitmap::kARGB_8888_Config, width, height);
        if (SkImageDecoder::kDecodeBounds_Mode == mode) {
            return true;
        }
        if (!this->allocPixelRef(bm, NULL)) {
            return false;
        }
    }

    //Create a format converter.
    SkTScopedComPtr<IWICFormatConverter> piFormatConverter;
    if (SUCCEEDED(hr)) {
        hr = piImagingFactory->CreateFormatConverter(&piFormatConverter);
    }

    if (SUCCEEDED(hr)) {
        hr = piFormatConverter->Initialize(
            piBitmapSourceOriginal.get()      //Input bitmap to convert
            , GUID_WICPixelFormat32bppPBGRA   //Destination pixel format
            , WICBitmapDitherTypeNone         //Specified dither patterm
            , NULL                            //Specify a particular palette
            , 0.f                             //Alpha threshold
            , WICBitmapPaletteTypeCustom      //Palette translation type
        );
    }

    //Get the BitmapSource interface of the format converter.
    SkTScopedComPtr<IWICBitmapSource> piBitmapSourceConverted;
    if (SUCCEEDED(hr)) {
        hr = piFormatConverter->QueryInterface(
            IID_PPV_ARGS(&piBitmapSourceConverted)
        );
    }

    //Copy the pixels into the bitmap.
    if (SUCCEEDED(hr)) {
        SkAutoLockPixels alp(*bm);
        bm->eraseColor(SK_ColorTRANSPARENT);
        const int stride = bm->rowBytes();
        hr = piBitmapSourceConverted->CopyPixels(
            NULL,                             //Get all the pixels
            stride,
            stride * height,
            reinterpret_cast<BYTE *>(bm->getPixels())
        );

        // Note: we don't need to premultiply here since we specified PBGRA
        bm->computeAndSetOpaquePredicate();
    }

    return SUCCEEDED(hr);
}

/////////////////////////////////////////////////////////////////////////

SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
    return SkNEW(SkImageDecoder_WIC);
}

/////////////////////////////////////////////////////////////////////////

SkMovie* SkMovie::DecodeStream(SkStream* stream) {
    return NULL;
}

/////////////////////////////////////////////////////////////////////////

class SkImageEncoder_WIC : public SkImageEncoder {
public:
    SkImageEncoder_WIC(Type t) : fType(t) {}

protected:
    virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality);

private:
    Type fType;
};

bool SkImageEncoder_WIC::onEncode(SkWStream* stream
                                , const SkBitmap& bitmapOrig
                                , int quality)
{
    GUID type;
    switch (fType) {
        case kJPEG_Type:
            type = GUID_ContainerFormatJpeg;
            break;
        case kPNG_Type:
            type = GUID_ContainerFormatPng;
            break;
        default:
            return false;
    }

    //Convert to 8888 if needed.
    const SkBitmap* bitmap;
    SkBitmap bitmapCopy;
    if (SkBitmap::kARGB_8888_Config == bitmapOrig.config() && bitmapOrig.isOpaque()) {
        bitmap = &bitmapOrig;
    } else {
        if (!bitmapOrig.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config)) {
            return false;
        }
        bitmap = &bitmapCopy;
    }

    // We cannot use PBGRA so we need to unpremultiply ourselves
    if (!bitmap->isOpaque()) {
        SkAutoLockPixels alp(*bitmap);

        uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap->getPixels());
        for (int y = 0; y < bitmap->height(); ++y) {
            for (int x = 0; x < bitmap->width(); ++x) {
                uint8_t* bytes = pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel();

                SkPMColor* src = reinterpret_cast<SkPMColor*>(bytes);
                SkColor* dst = reinterpret_cast<SkColor*>(bytes);

                *dst = SkUnPreMultiply::PMColorToColor(*src);
            }
        }
    }

    //Initialize COM.
    SkAutoCoInitialize scopedCo;
    if (!scopedCo.succeeded()) {
        return false;
    }

    HRESULT hr = S_OK;

    //Create Windows Imaging Component ImagingFactory.
    SkTScopedComPtr<IWICImagingFactory> piImagingFactory;
    if (SUCCEEDED(hr)) {
        hr = CoCreateInstance(
            CLSID_WICImagingFactory
            , NULL
            , CLSCTX_INPROC_SERVER
            , IID_PPV_ARGS(&piImagingFactory)
        );
    }

    //Convert the SkWStream to an IStream.
    SkTScopedComPtr<IStream> piStream;
    if (SUCCEEDED(hr)) {
        hr = SkWIStream::CreateFromSkWStream(stream, &piStream);
    }

    //Create an encode of the appropriate type.
    SkTScopedComPtr<IWICBitmapEncoder> piEncoder;
    if (SUCCEEDED(hr)) {
        hr = piImagingFactory->CreateEncoder(type, NULL, &piEncoder);
    }

    if (SUCCEEDED(hr)) {
        hr = piEncoder->Initialize(piStream.get(), WICBitmapEncoderNoCache);
    }

    //Create a the frame.
    SkTScopedComPtr<IWICBitmapFrameEncode> piBitmapFrameEncode;
    SkTScopedComPtr<IPropertyBag2> piPropertybag;
    if (SUCCEEDED(hr)) {
        hr = piEncoder->CreateNewFrame(&piBitmapFrameEncode, &piPropertybag);
    }

    if (SUCCEEDED(hr)) {
        PROPBAG2 name = { 0 };
        name.dwType = PROPBAG2_TYPE_DATA;
        name.vt = VT_R4;
        name.pstrName = L"ImageQuality";

        VARIANT value;
        VariantInit(&value);
        value.vt = VT_R4;
        value.fltVal = (FLOAT)(quality / 100.0);

        //Ignore result code.
        //  This returns E_FAIL if the named property is not in the bag.
        //TODO(bungeman) enumerate the properties,
        //  write and set hr iff property exists.
        piPropertybag->Write(1, &name, &value);
    }
    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameEncode->Initialize(piPropertybag.get());
    }

    //Set the size of the frame.
    const UINT width = bitmap->width();
    const UINT height = bitmap->height();
    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameEncode->SetSize(width, height);
    }

    //Set the pixel format of the frame.
    const WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA;
    WICPixelFormatGUID formatGUID = formatDesired;
    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameEncode->SetPixelFormat(&formatGUID);
    }
    if (SUCCEEDED(hr)) {
        //Be sure the image format is the one requested.
        hr = IsEqualGUID(formatGUID, formatDesired) ? S_OK : E_FAIL;
    }

    //Write the pixels into the frame.
    if (SUCCEEDED(hr)) {
        SkAutoLockPixels alp(*bitmap);
        hr = piBitmapFrameEncode->WritePixels(
            height
            , bitmap->rowBytes()
            , bitmap->rowBytes()*height
            , reinterpret_cast<BYTE*>(bitmap->getPixels()));
    }

    if (SUCCEEDED(hr)) {
        hr = piBitmapFrameEncode->Commit();
    }

    if (SUCCEEDED(hr)) {
        hr = piEncoder->Commit();
    }

    return SUCCEEDED(hr);
}

SkImageEncoder* SkImageEncoder::Create(Type t) {
    switch (t) {
        case kJPEG_Type:
        case kPNG_Type:
            break;
        default:
            return NULL;
    }
    return SkNEW_ARGS(SkImageEncoder_WIC, (t));
}

<|endoftext|>