<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, Image Engine Design Inc. 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 Image Engine Design nor the names of any
//       other contributors to this software 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 "boost/static_assert.hpp"
#include "boost/format.hpp"

#include "IECore/TIFFImageWriter.h"
#include "IECore/MessageHandler.h"
#include "IECore/VectorTypedData.h"
#include "IECore/ByteOrder.h"
#include "IECore/ImagePrimitive.h"
#include "IECore/FileNameParameter.h"
#include "IECore/Parameter.h"
#include "IECore/NumericParameter.h"

#include "IECore/BoxOperators.h"

#include "tiffio.h"

using namespace IECore;
using namespace std;
using namespace boost;
using namespace Imath;

const Writer::WriterDescription<TIFFImageWriter> TIFFImageWriter::m_writerDescription("tiff tif");

TIFFImageWriter::TIFFImageWriter() 
	: 	ImageWriter("TIFFImageWriter", "Serializes images to the Tagged Image File Format (TIFF) format")
{
	constructParameters();
}

TIFFImageWriter::TIFFImageWriter(ObjectPtr image, const string & fileName) 
	: 	ImageWriter("TIFFImageWriter", "Serializes images to the Tagged Image File Format (TIFF) format")
{
	constructParameters();
	m_objectParameter->setValue( image );
	m_fileNameParameter->setTypedValue( fileName );
}

void TIFFImageWriter::constructParameters( )
{
	// bitdepth parameter
	m_bitdepthParameter = new IntParameter("bitdepth", "output TIFF bit depth, one of 8, 16, 32; defaults to 16");
	parameters()->addParameter(m_bitdepthParameter);

	// compression parameter
	IntParameter::PresetsMap compressionPresets;
	compressionPresets["none"]    = COMPRESSION_NONE;
	compressionPresets["lzw"]     = COMPRESSION_LZW;
	compressionPresets["jpeg"]    = COMPRESSION_JPEG;
	compressionPresets["deflate"] = COMPRESSION_DEFLATE;

	/// Verify min
	BOOST_STATIC_ASSERT( COMPRESSION_NONE < COMPRESSION_LZW );	
	BOOST_STATIC_ASSERT( COMPRESSION_NONE < COMPRESSION_JPEG );		
	BOOST_STATIC_ASSERT( COMPRESSION_NONE < COMPRESSION_DEFLATE );	

	/// Verify max
	BOOST_STATIC_ASSERT( COMPRESSION_DEFLATE > COMPRESSION_NONE );	
	BOOST_STATIC_ASSERT( COMPRESSION_DEFLATE > COMPRESSION_LZW );		
	BOOST_STATIC_ASSERT( COMPRESSION_DEFLATE > COMPRESSION_JPEG );


	m_compressionParameter = new IntParameter("compression", "image data compression method",
		compressionPresets["lzw"], 
		COMPRESSION_NONE,
		COMPRESSION_DEFLATE,
		compressionPresets, 
		true);
		
	parameters()->addParameter(m_compressionParameter);
}

TIFFImageWriter::~TIFFImageWriter()
{
}

void TIFFImageWriter::stripEncode(tiff * tiff_image, char * image_buffer, int image_buffer_size, int strips)
{
	// write the information to the file
	int offset = 0;

	for(int strip = 0; strip < strips; ++strip)
	{
		int tss = TIFFStripSize(tiff_image);
		int remaining = image_buffer_size - offset;
		int lc = TIFFWriteEncodedStrip(tiff_image, strip, image_buffer + offset,
												 tss < remaining ? tss : remaining);
		offset += lc;
	}
}


void TIFFImageWriter::writeImage(vector<string> & names, ConstImagePrimitivePtr image, const Box2i & dw)
{	
	// create the tiff file
	TIFF *tiff_image;
	if((tiff_image = TIFFOpen(fileName().c_str(), "w")) == NULL)
	{
		throw IOException("Could not open '" + fileName() + "' for writing.");
	}

	// compute the writebox	
	int width  = 1 + dw.max.x - dw.min.x;
	int height = 1 + dw.max.y - dw.min.y;

	// compute the number of channels
	int spp = names.size();

	/// \todo different compression methods have a bearing on other attributes, eg. the strip size
	/// handle these issues a bit better and perhaps more explicitly here.  also, we should probably<commit_msg>Added parameter presets and libtiff error handling.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, Image Engine Design Inc. 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 Image Engine Design nor the names of any
//       other contributors to this software 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 "boost/static_assert.hpp"
#include "boost/format.hpp"

#include "IECore/TIFFImageWriter.h"
#include "IECore/MessageHandler.h"
#include "IECore/VectorTypedData.h"
#include "IECore/ByteOrder.h"
#include "IECore/ImagePrimitive.h"
#include "IECore/FileNameParameter.h"
#include "IECore/Parameter.h"
#include "IECore/NumericParameter.h"
#include "IECore/ScopedTIFFExceptionTranslator.h"

#include "IECore/BoxOperators.h"

#include "tiffio.h"

using namespace IECore;
using namespace std;
using namespace boost;
using namespace Imath;

const Writer::WriterDescription<TIFFImageWriter> TIFFImageWriter::m_writerDescription("tiff tif");

TIFFImageWriter::TIFFImageWriter() 
	: 	ImageWriter("TIFFImageWriter", "Serializes images to the Tagged Image File Format (TIFF) format")
{
	constructParameters();
}

TIFFImageWriter::TIFFImageWriter(ObjectPtr image, const string & fileName) 
	: 	ImageWriter("TIFFImageWriter", "Serializes images to the Tagged Image File Format (TIFF) format")
{
	constructParameters();
	m_objectParameter->setValue( image );
	m_fileNameParameter->setTypedValue( fileName );
}

void TIFFImageWriter::constructParameters( )
{
	// bitdepth parameter
	IntParameter::PresetsMap bitDepthPresets;
	bitDepthPresets["8"] = 8;
	bitDepthPresets["16"] = 16;	
	bitDepthPresets["32"] = 32;	
	
	m_bitdepthParameter = new IntParameter(
		"bitdepth", 
		"Output TIFF bit depth",
		16,
		8,
		32,
		bitDepthPresets,
		true);
		
	parameters()->addParameter(m_bitdepthParameter);

	// compression parameter
	IntParameter::PresetsMap compressionPresets;
	compressionPresets["none"]    = COMPRESSION_NONE;
	compressionPresets["lzw"]     = COMPRESSION_LZW;
	compressionPresets["jpeg"]    = COMPRESSION_JPEG;
	compressionPresets["deflate"] = COMPRESSION_DEFLATE;

	/// Verify min
	BOOST_STATIC_ASSERT( COMPRESSION_NONE < COMPRESSION_LZW );	
	BOOST_STATIC_ASSERT( COMPRESSION_NONE < COMPRESSION_JPEG );		
	BOOST_STATIC_ASSERT( COMPRESSION_NONE < COMPRESSION_DEFLATE );	

	/// Verify max
	BOOST_STATIC_ASSERT( COMPRESSION_DEFLATE > COMPRESSION_NONE );	
	BOOST_STATIC_ASSERT( COMPRESSION_DEFLATE > COMPRESSION_LZW );		
	BOOST_STATIC_ASSERT( COMPRESSION_DEFLATE > COMPRESSION_JPEG );


	m_compressionParameter = new IntParameter("compression", "image data compression method",
		compressionPresets["lzw"], 
		COMPRESSION_NONE,
		COMPRESSION_DEFLATE,
		compressionPresets, 
		true);
		
	parameters()->addParameter(m_compressionParameter);
}

TIFFImageWriter::~TIFFImageWriter()
{
}

void TIFFImageWriter::stripEncode(tiff * tiff_image, char * image_buffer, int image_buffer_size, int strips)
{	
	// write the information to the file
	int offset = 0;

	for(int strip = 0; strip < strips; ++strip)
	{
		int tss = TIFFStripSize(tiff_image);
		int remaining = image_buffer_size - offset;
		int lc = TIFFWriteEncodedStrip(tiff_image, strip, image_buffer + offset,
												 tss < remaining ? tss : remaining);
		offset += lc;
	}
}


void TIFFImageWriter::writeImage(vector<string> & names, ConstImagePrimitivePtr image, const Box2i & dw)
{	
	ScopedTIFFExceptionTranslator errorHandler( );

	// create the tiff file
	TIFF *tiff_image;
	if((tiff_image = TIFFOpen(fileName().c_str(), "w")) == NULL)
	{
		throw IOException("Could not open '" + fileName() + "' for writing.");
	}

	// compute the writebox	
	int width  = 1 + dw.max.x - dw.min.x;
	int height = 1 + dw.max.y - dw.min.y;

	// compute the number of channels
	int spp = names.size();

	/// \todo different compression methods have a bearing on other attributes, eg. the strip size
	/// handle these issues a bit better and perhaps more explicitly here.  also, we should probably
{'fraction_non_alphanumeric': 0.12016407196793139, 'fraction_numerical': 0.003728908362077002, 'mean_word_length': 3.8653061224489798, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '643095', 'n_tokens_mistral': 3324, 'n_tokens_neox': 3129, 'n_words': 991}