|
Moritz Grosch (LittleFox) |
5352f3 |
/* === S Y N F I G ========================================================= */
|
|
Moritz Grosch (LittleFox) |
5352f3 |
/*! \file trgt_png_spriteengine.cpp
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** \brief png_trgt Target Module
|
|
Moritz Grosch (LittleFox) |
5352f3 |
**
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** $Id$
|
|
Moritz Grosch (LittleFox) |
5352f3 |
**
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** \legal
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** Copyright (c) 2007 Chris Moore
|
|
|
2ed9df |
** Copyright (c) 2013 Moritz Grosch (LittleFox) <littlefox@fsfe.org></littlefox@fsfe.org>
|
|
Moritz Grosch (LittleFox) |
5352f3 |
**
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** Based on trgt_png.cpp
|
|
Moritz Grosch (LittleFox) |
5352f3 |
**
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** This package is free software; you can redistribute it and/or
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** modify it under the terms of the GNU General Public License as
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** published by the Free Software Foundation; either version 2 of
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** the License, or (at your option) any later version.
|
|
Moritz Grosch (LittleFox) |
5352f3 |
**
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** This package is distributed in the hope that it will be useful,
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** General Public License for more details.
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** \endlegal
|
|
Moritz Grosch (LittleFox) |
5352f3 |
**
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** === N O T E S ===========================================================
|
|
Moritz Grosch (LittleFox) |
5352f3 |
**
|
|
Moritz Grosch (LittleFox) |
5352f3 |
** ========================================================================= */
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
/* === H E A D E R S ======================================================= */
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#ifdef USING_PCH
|
|
Moritz Grosch (LittleFox) |
5352f3 |
# include "pch.h"
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#else
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#ifdef HAVE_CONFIG_H
|
|
Moritz Grosch (LittleFox) |
5352f3 |
# include <config.h></config.h>
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#endif
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
bw |
94d8a6 |
#include <synfig localization.h=""></synfig>
|
|
bw |
94d8a6 |
#include <synfig general.h=""></synfig>
|
|
bw |
94d8a6 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#include "trgt_png_spritesheet.h"
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#include <png.h></png.h>
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#include <etl stringf=""></etl>
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#include <cstdio></cstdio>
|
|
|
337598 |
#include <cstring> </cstring>
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#include <algorithm></algorithm>
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#include <functional></functional>
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#include <etl misc=""></etl>
|
|
trizer |
613172 |
#include <iostream></iostream>
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
#endif
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
/* === M A C R O S ========================================================= */
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
using namespace synfig;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
using namespace std;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
using namespace etl;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
/* === G L O B A L S ======================================================= */
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
SYNFIG_TARGET_INIT(png_trgt_spritesheet);
|
|
|
2ed9df |
SYNFIG_TARGET_SET_NAME(png_trgt_spritesheet,"png-spritesheet");
|
|
|
2ed9df |
SYNFIG_TARGET_SET_EXT(png_trgt_spritesheet,"png");
|
|
Moritz Grosch (LittleFox) |
5352f3 |
SYNFIG_TARGET_SET_VERSION(png_trgt_spritesheet,"0.1");
|
|
Moritz Grosch (LittleFox) |
5352f3 |
SYNFIG_TARGET_SET_CVS_ID(png_trgt_spritesheet,"$Id$");
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
/* === M E T H O D S ======================================================= */
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
void
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet::png_out_error(png_struct *png_data,const char *msg)
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet *me=(png_trgt_spritesheet*)png_get_error_ptr(png_data);
|
|
Moritz Grosch (LittleFox) |
5352f3 |
synfig::error(strprintf("png_trgt_spritesheet: error: %s",msg));
|
|
Moritz Grosch (LittleFox) |
5352f3 |
me->ready=false;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
void
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet::png_out_warning(png_struct *png_data,const char *msg)
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet *me=(png_trgt_spritesheet*)png_get_error_ptr(png_data);
|
|
Moritz Grosch (LittleFox) |
5352f3 |
synfig::warning(strprintf("png_trgt_spritesheet: warning: %s",msg));
|
|
Moritz Grosch (LittleFox) |
5352f3 |
me->ready=false;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
//Target *png_trgt::New(const char *filename){ return new png_trgt(filename);}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
|
6320b8 |
png_trgt_spritesheet::png_trgt_spritesheet(const char *Filename, const synfig::TargetParam ¶ms):
|
|
|
6320b8 |
ready(false),
|
|
|
6320b8 |
initialized(false),
|
|
|
6320b8 |
imagecount(),
|
|
|
6320b8 |
lastimage(),
|
|
|
6320b8 |
numimages(),
|
|
trizer |
613172 |
cur_y(0),
|
|
trizer |
d2fcc7 |
cur_row(0),
|
|
trizer |
d2fcc7 |
cur_col(0),
|
|
trizer |
613172 |
params(params),
|
|
trizer |
613172 |
color_data(0),
|
|
trizer |
613172 |
sheet_width(0),
|
|
trizer |
613172 |
sheet_height(0),
|
|
trizer |
613172 |
in_file_pointer(0),
|
|
|
e8b33d |
out_file_pointer(0),
|
|
|
e8b33d |
cur_out_image_row(0),
|
|
|
6320b8 |
filename(Filename),
|
|
Denis Zdorovtsov |
76fe0c |
sequence_separator(params.sequence_separator),
|
|
Denis Zdorovtsov |
76fe0c |
overflow_buff(0)
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
trizer |
4e2b93 |
cout << "png_trgt_spritesheet() " << params.offset_x << " " << params.offset_y << endl;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet::~png_trgt_spritesheet()
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
trizer |
613172 |
cout << "~png_trgt_spritesheet()" << endl;
|
|
trizer |
613172 |
if (ready)
|
|
trizer |
613172 |
write_png_file ();
|
|
trizer |
613172 |
if (color_data)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
for (unsigned int i = 0; i < sheet_height; i++)
|
|
trizer |
613172 |
delete []color_data[i];
|
|
trizer |
613172 |
delete []color_data;
|
|
trizer |
613172 |
}
|
|
Denis Zdorovtsov |
76fe0c |
if (overflow_buff)
|
|
Denis Zdorovtsov |
76fe0c |
delete []overflow_buff;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
bool
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet::set_rend_desc(RendDesc *given_desc)
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
trizer |
613172 |
cout << "set_rend_desc()" << endl;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
//given_desc->set_pixel_format(PixelFormat((int)PF_RGB|(int)PF_A));
|
|
Moritz Grosch (LittleFox) |
5352f3 |
desc=*given_desc;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
imagecount=desc.get_frame_start();
|
|
Moritz Grosch (LittleFox) |
5352f3 |
lastimage=desc.get_frame_end();
|
|
Denis Zdorovtsov |
76fe0c |
numimages = (lastimage - imagecount) + 1;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Denis Zdorovtsov |
76fe0c |
overflow_buff = new Color[desc.get_w()];
|
|
Denis Zdorovtsov |
76fe0c |
|
|
Denis Zdorovtsov |
76fe0c |
//Reset on uninitialized values
|
|
Denis Zdorovtsov |
76fe0c |
if ((params.columns == 0) || (params.rows == 0))
|
|
Denis Zdorovtsov |
76fe0c |
{
|
|
luz.paz |
55f599 |
cout << "Uninitialized sheet parameters. Reset parameters." << endl;
|
|
trizer |
d2fcc7 |
params.columns = numimages;
|
|
Denis Zdorovtsov |
76fe0c |
params.rows = 1;
|
|
Denis Zdorovtsov |
76fe0c |
params.append = true;
|
|
Denis Zdorovtsov |
76fe0c |
params.dir = TargetParam::HR;
|
|
Denis Zdorovtsov |
76fe0c |
}
|
|
Denis Zdorovtsov |
76fe0c |
|
|
Denis Zdorovtsov |
76fe0c |
//Break on overflow
|
|
Denis Zdorovtsov |
76fe0c |
if (params.columns * params.rows < numimages)
|
|
Denis Zdorovtsov |
76fe0c |
{
|
|
Denis Zdorovtsov |
76fe0c |
cout << "Sheet overflow. Break." << endl;
|
|
Denis Zdorovtsov |
76fe0c |
synfig::error("Bad sheet parameters. Sheet overflow.");
|
|
Denis Zdorovtsov |
76fe0c |
return false;
|
|
Denis Zdorovtsov |
76fe0c |
}
|
|
trizer |
d2fcc7 |
|
|
trizer |
613172 |
cout << "Frame count" << numimages << endl;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
trizer |
613172 |
bool is_loaded = false;
|
|
Denis Zdorovtsov |
76fe0c |
|
|
Denis Zdorovtsov |
76fe0c |
if (params.append)
|
|
trizer |
613172 |
{
|
|
Denis Zdorovtsov |
76fe0c |
in_file_pointer = fopen(filename.c_str(), "rb");
|
|
Denis Zdorovtsov |
76fe0c |
if (!in_file_pointer)
|
|
Denis Zdorovtsov |
76fe0c |
synfig::error(strprintf("[read_png_file] File %s could not be opened for reading", filename.c_str()));
|
|
Denis Zdorovtsov |
76fe0c |
else
|
|
Denis Zdorovtsov |
76fe0c |
{
|
|
Denis Zdorovtsov |
76fe0c |
is_loaded = load_png_file();
|
|
Denis Zdorovtsov |
76fe0c |
if (!is_loaded)
|
|
Denis Zdorovtsov |
76fe0c |
fclose(in_file_pointer);
|
|
Denis Zdorovtsov |
76fe0c |
}
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
//I select such size which appropriate to contain whole sprite sheet.
|
|
trizer |
d2fcc7 |
unsigned int target_width = params.columns * desc.get_w() + params.offset_x;
|
|
trizer |
d2fcc7 |
unsigned int target_height = params.rows * desc.get_h() + params.offset_y;
|
|
trizer |
613172 |
sheet_width = in_image.width > target_width? in_image.width : target_width;
|
|
trizer |
613172 |
sheet_height = in_image.height > target_height? in_image.height : target_height;
|
|
trizer |
613172 |
|
|
trizer |
613172 |
if (sheet_width * sheet_height > 5000 * 2000)
|
|
trizer |
613172 |
{
|
|
luz.paz |
55f599 |
synfig::error(strprintf(_("The image is too large. It's size must be not more than 5000*2000=10000000 px. Currently it's %d*%d=%d px."),
|
|
trizer |
613172 |
sheet_width, sheet_height, sheet_width * sheet_height));
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
cout << "Sheet size: " << sheet_width << "x" << sheet_height << endl;
|
|
trizer |
613172 |
|
|
trizer |
613172 |
cout << "Color size: " << sizeof(Color) << endl;
|
|
trizer |
613172 |
|
|
trizer |
613172 |
color_data = new Color*[sheet_height];
|
|
trizer |
613172 |
for (unsigned int i = 0; i < sheet_height; i++)
|
|
trizer |
613172 |
color_data[i] = new Color[sheet_width];
|
|
trizer |
613172 |
|
|
trizer |
613172 |
if (is_loaded)
|
|
trizer |
613172 |
ready = read_png_file();
|
|
trizer |
613172 |
else
|
|
trizer |
613172 |
ready = true;
|
|
trizer |
613172 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
return true;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
void
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet::end_frame()
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
trizer |
613172 |
cout << "end_frame()" << endl;
|
|
trizer |
613172 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
imagecount++;
|
|
trizer |
613172 |
cur_y = 0;
|
|
Denis Zdorovtsov |
76fe0c |
if (params.dir == TargetParam::HR)
|
|
Denis Zdorovtsov |
76fe0c |
{
|
|
Pascal Schmid |
2891f7 |
//Horizontal render. Columns increment
|
|
Denis Zdorovtsov |
76fe0c |
cur_col++;
|
|
Denis Zdorovtsov |
76fe0c |
if (cur_col >= (unsigned int)params.columns)
|
|
Denis Zdorovtsov |
76fe0c |
{
|
|
Denis Zdorovtsov |
76fe0c |
cur_row++;
|
|
Denis Zdorovtsov |
76fe0c |
cur_col = 0;
|
|
Denis Zdorovtsov |
76fe0c |
}
|
|
Denis Zdorovtsov |
76fe0c |
}
|
|
Denis Zdorovtsov |
76fe0c |
else
|
|
trizer |
d2fcc7 |
{
|
|
Denis Zdorovtsov |
76fe0c |
//Vertical render. Rows increment.
|
|
trizer |
d2fcc7 |
cur_row++;
|
|
Denis Zdorovtsov |
76fe0c |
if (cur_row >= (unsigned int) params.rows)
|
|
Denis Zdorovtsov |
76fe0c |
{
|
|
Denis Zdorovtsov |
76fe0c |
cur_col++;
|
|
Denis Zdorovtsov |
76fe0c |
cur_row = 0;
|
|
Denis Zdorovtsov |
76fe0c |
}
|
|
trizer |
d2fcc7 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
bool
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet::start_frame(synfig::ProgressCallback *callback)
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
trizer |
613172 |
cout << "start_frame()" << endl;
|
|
trizer |
613172 |
if(callback)
|
|
trizer |
613172 |
callback->task(strprintf("%s, (frame %d/%d)", filename.c_str(),
|
|
trizer |
613172 |
imagecount - (lastimage - numimages), numimages).c_str());
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
return true;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
Color *
|
|
Moritz Grosch (LittleFox) |
5352f3 |
png_trgt_spritesheet::start_scanline(int /*scanline*/)
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
Denis Zdorovtsov |
76fe0c |
unsigned int y = cur_y + params.offset_y + cur_row * desc.get_h();
|
|
Denis Zdorovtsov |
76fe0c |
unsigned int x = cur_col * desc.get_w() + params.offset_x;
|
|
Denis Zdorovtsov |
76fe0c |
if ((x + desc.get_w() > sheet_width) || (y > sheet_height))
|
|
Denis Zdorovtsov |
76fe0c |
{
|
|
Denis Zdorovtsov |
76fe0c |
cout << "Buffer overflow. x: " << x << " y: " << y << endl;
|
|
Denis Zdorovtsov |
76fe0c |
//TODO: Fix exception processing outside the module.
|
|
Denis Zdorovtsov |
76fe0c |
return overflow_buff; //Spike. Bad exception processing
|
|
Denis Zdorovtsov |
76fe0c |
}
|
|
Denis Zdorovtsov |
76fe0c |
return &color_data[y][x];
|
|
trizer |
613172 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
trizer |
613172 |
bool
|
|
trizer |
613172 |
png_trgt_spritesheet::end_scanline()
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
cur_y++;
|
|
trizer |
613172 |
return true;
|
|
trizer |
613172 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
trizer |
613172 |
//The func only loads file. Reading into the buffer in read_png_file().
|
|
trizer |
613172 |
bool
|
|
trizer |
613172 |
png_trgt_spritesheet::load_png_file()
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
cout << "load_png_file()" << endl;
|
|
trizer |
613172 |
|
|
trizer |
613172 |
char header[8]; // 8 is the maximum size that can be checked
|
|
trizer |
613172 |
|
|
trizer |
613172 |
//Reads header for next checking.
|
|
trizer |
4e2b93 |
int length = fread(header, 1, 8, in_file_pointer);
|
|
trizer |
d2fcc7 |
if ((length != 8) || png_sig_cmp((unsigned char *)header, 0, 8))
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error(strprintf("[read_png_file] File %s is not recognized as a PNG file", filename.c_str()));
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
/* initialize stuff */
|
|
trizer |
613172 |
in_image.png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
trizer |
613172 |
|
|
trizer |
613172 |
if (!in_image.png_ptr)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error("[read_png_file] png_create_read_struct failed");
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
in_image.info_ptr = png_create_info_struct(in_image.png_ptr);
|
|
trizer |
613172 |
if (!in_image.info_ptr)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error("[read_png_file] png_create_info_struct failed");
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
if (setjmp(png_jmpbuf(in_image.png_ptr)))
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error("[read_png_file] Error during init_io");
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
png_init_io(in_image.png_ptr, in_file_pointer);
|
|
trizer |
613172 |
png_set_sig_bytes(in_image.png_ptr, 8);
|
|
trizer |
613172 |
|
|
trizer |
613172 |
png_read_info(in_image.png_ptr, in_image.info_ptr);
|
|
trizer |
613172 |
|
|
trizer |
613172 |
in_image.width = png_get_image_width(in_image.png_ptr, in_image.info_ptr);
|
|
trizer |
613172 |
in_image.height = png_get_image_height(in_image.png_ptr, in_image.info_ptr);
|
|
trizer |
613172 |
cout << "Img size: " << in_image.width << "x" << in_image.height << endl;
|
|
trizer |
613172 |
in_image.color_type = png_get_color_type(in_image.png_ptr, in_image.info_ptr);
|
|
trizer |
613172 |
in_image.bit_depth = png_get_bit_depth(in_image.png_ptr, in_image.info_ptr);
|
|
trizer |
613172 |
|
|
trizer |
613172 |
png_read_update_info(in_image.png_ptr, in_image.info_ptr);
|
|
trizer |
613172 |
|
|
trizer |
613172 |
|
|
trizer |
613172 |
/* read file */
|
|
trizer |
613172 |
if (setjmp(png_jmpbuf(in_image.png_ptr)))
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error("[read_png_file] Error during read_image");
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
return true;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
bool
|
|
trizer |
613172 |
png_trgt_spritesheet::read_png_file()
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
cout << "read_png_file()" << endl;
|
|
trizer |
613172 |
//Byte buffer for png data
|
|
trizer |
613172 |
png_bytep * row_pointers;
|
|
trizer |
613172 |
row_pointers = new png_bytep[in_image.height];
|
|
trizer |
613172 |
for (unsigned int y = 0; y < in_image.height; y++)
|
|
trizer |
613172 |
row_pointers[y] = new png_byte[png_get_rowbytes(in_image.png_ptr,in_image.info_ptr)];
|
|
trizer |
613172 |
cout << "row_pointers created" << endl;
|
|
trizer |
613172 |
|
|
trizer |
613172 |
png_read_image(in_image.png_ptr, row_pointers);
|
|
trizer |
613172 |
cout << "image read" << endl;
|
|
trizer |
613172 |
|
|
trizer |
613172 |
if (png_get_color_type(in_image.png_ptr, in_image.info_ptr) == PNG_COLOR_TYPE_RGB)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGBA "
|
|
trizer |
613172 |
"(lacks the alpha channel)");
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
if (png_get_color_type(in_image.png_ptr, in_image.info_ptr) != PNG_COLOR_TYPE_RGBA)
|
|
trizer |
613172 |
{
|
|
|
80b15f |
synfig::error("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (%d) (is %d)",
|
|
|
80b15f |
PNG_COLOR_TYPE_RGBA, png_get_color_type(in_image.png_ptr, in_image.info_ptr));
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
613172 |
cout << "colors checked" << endl;
|
|
trizer |
613172 |
|
|
luz.paz |
99f3ef |
//From png bytes to synfig::Color conversion
|
|
|
a4bbdd |
const ColorReal k = 1/255.0;
|
|
trizer |
613172 |
for (unsigned int y = 0; y < in_image.height; y++)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
png_byte* row = row_pointers[y];
|
|
trizer |
613172 |
for (unsigned int x = 0; x < in_image.width; x++)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
png_byte* ptr = &(row[x*4]);
|
|
|
a4bbdd |
color_data[y][x].set_r(ptr[0]*k);
|
|
|
a4bbdd |
color_data[y][x].set_g(ptr[1]*k);
|
|
|
a4bbdd |
color_data[y][x].set_b(ptr[2]*k);
|
|
|
a4bbdd |
color_data[y][x].set_a(ptr[3]*k);
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
trizer |
613172 |
cout << "colors converted" << endl;
|
|
trizer |
613172 |
|
|
trizer |
613172 |
for (unsigned int y = 0; y < in_image.height; y++)
|
|
trizer |
613172 |
delete []row_pointers[y];
|
|
|
80b15f |
|
|
|
80b15f |
delete[] row_pointers;
|
|
trizer |
613172 |
cout << "row_pointers deleted" << endl;
|
|
trizer |
613172 |
return true;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
trizer |
613172 |
bool
|
|
trizer |
613172 |
png_trgt_spritesheet::write_png_file()
|
|
Moritz Grosch (LittleFox) |
5352f3 |
{
|
|
trizer |
613172 |
cout << "write_png_file()" << endl;
|
|
trizer |
613172 |
png_structp png_ptr;
|
|
trizer |
613172 |
png_infop info_ptr;
|
|
trizer |
613172 |
unsigned char buffer [4 * sheet_width];
|
|
trizer |
4e2b93 |
|
|
trizer |
613172 |
|
|
trizer |
613172 |
if (filename == "-")
|
|
|
e8b33d |
out_file_pointer=stdout;
|
|
trizer |
613172 |
else
|
|
|
e8b33d |
out_file_pointer=fopen(filename.c_str(), POPEN_BINARY_WRITE_TYPE);
|
|
trizer |
613172 |
|
|
trizer |
4e2b93 |
|
|
trizer |
613172 |
png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)this,png_out_error, png_out_warning);
|
|
trizer |
613172 |
if (!png_ptr)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error("Unable to setup PNG struct");
|
|
|
e8b33d |
fclose(out_file_pointer);
|
|
|
e8b33d |
out_file_pointer=NULL;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
return false;
|
|
trizer |
613172 |
}
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
trizer |
4e2b93 |
|
|
trizer |
613172 |
info_ptr= png_create_info_struct(png_ptr);
|
|
trizer |
613172 |
if (!info_ptr)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error("Unable to setup PNG info struct");
|
|
|
e8b33d |
fclose(out_file_pointer);
|
|
|
e8b33d |
out_file_pointer=NULL;
|
|
trizer |
613172 |
png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
|
|
trizer |
4e2b93 |
|
|
trizer |
613172 |
if (setjmp(png_jmpbuf(png_ptr)))
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
synfig::error("Unable to setup longjump");
|
|
trizer |
613172 |
png_destroy_write_struct(&png_ptr, &info_ptr);
|
|
|
e8b33d |
fclose(out_file_pointer);
|
|
|
e8b33d |
out_file_pointer=NULL;
|
|
trizer |
613172 |
return false;
|
|
trizer |
613172 |
}
|
|
|
e8b33d |
png_init_io(png_ptr,out_file_pointer);
|
|
trizer |
613172 |
png_set_filter(png_ptr,0,PNG_FILTER_NONE);
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
trizer |
4e2b93 |
|
|
Moritz Grosch (LittleFox) |
5352f3 |
setjmp(png_jmpbuf(png_ptr));
|
|
Moritz Grosch (LittleFox) |
5352f3 |
|
|
trizer |
613172 |
png_set_IHDR(png_ptr,info_ptr,
|
|
trizer |
613172 |
sheet_width,
|
|
trizer |
613172 |
sheet_height,
|
|
trizer |
613172 |
8,
|
|
trizer |
613172 |
(get_alpha_mode()==TARGET_ALPHA_MODE_KEEP)?PNG_COLOR_TYPE_RGBA:PNG_COLOR_TYPE_RGB,
|
|
trizer |
613172 |
PNG_INTERLACE_NONE,
|
|
trizer |
613172 |
PNG_COMPRESSION_TYPE_DEFAULT,
|
|
trizer |
613172 |
PNG_FILTER_TYPE_DEFAULT);
|
|
trizer |
613172 |
|
|
trizer |
613172 |
// Write the physical size
|
|
trizer |
613172 |
png_set_pHYs(png_ptr,info_ptr,round_to_int(desc.get_x_res()),round_to_int(desc.get_y_res()),PNG_RESOLUTION_METER);
|
|
trizer |
613172 |
|
|
trizer |
613172 |
char title [] = "Title";
|
|
trizer |
613172 |
char description[] = "Description";
|
|
trizer |
613172 |
char software [] = "Software";
|
|
trizer |
613172 |
char synfig [] = "SYNFIG";
|
|
|
93c6c7 |
|
|
|
93c6c7 |
// Output any text info along with the file
|
|
|
93c6c7 |
png_text comments[3];
|
|
|
93c6c7 |
memset(comments, 0, sizeof(comments));
|
|
|
93c6c7 |
|
|
|
93c6c7 |
comments[0].compression = PNG_TEXT_COMPRESSION_NONE;
|
|
|
93c6c7 |
comments[0].key = title;
|
|
|
93c6c7 |
comments[0].text = const_cast<char *="">(get_canvas()->get_name().c_str());</char>
|
|
|
93c6c7 |
comments[0].text_length = strlen(comments[0].text);
|
|
|
93c6c7 |
|
|
|
93c6c7 |
comments[1].compression = PNG_TEXT_COMPRESSION_NONE;
|
|
|
93c6c7 |
comments[1].key = description;
|
|
|
93c6c7 |
comments[1].text = const_cast<char *="">(get_canvas()->get_description().c_str());</char>
|
|
|
93c6c7 |
comments[1].text_length = strlen(comments[1].text);
|
|
|
93c6c7 |
|
|
|
93c6c7 |
comments[2].compression = PNG_TEXT_COMPRESSION_NONE;
|
|
|
93c6c7 |
comments[2].key = software;
|
|
|
93c6c7 |
comments[2].text = synfig;
|
|
|
93c6c7 |
comments[2].text_length = strlen(comments[2].text);
|
|
|
93c6c7 |
|
|
|
93c6c7 |
png_set_text(png_ptr, info_ptr, comments, sizeof(comments)/sizeof(png_text));
|
|
trizer |
613172 |
|
|
trizer |
613172 |
png_write_info_before_PLTE(png_ptr, info_ptr);
|
|
trizer |
613172 |
png_write_info(png_ptr, info_ptr);
|
|
|
e8b33d |
|
|
|
e8b33d |
//Writing spritesheet into png image
|
|
|
e8b33d |
for (cur_out_image_row = 0; cur_out_image_row < sheet_height; cur_out_image_row++)
|
|
trizer |
613172 |
{
|
|
|
d21b46 |
color_to_pixelformat(
|
|
|
d21b46 |
buffer,
|
|
|
d21b46 |
color_data[cur_out_image_row],
|
|
|
d21b46 |
//PF_RGB|(get_alpha_mode()==TARGET_ALPHA_MODE_KEEP)?PF_A:PF_RGB, //Note: PF_RGB == 0
|
|
|
d21b46 |
(get_alpha_mode() == TARGET_ALPHA_MODE_KEEP) ? PF_RGB | PF_A : PF_RGB, //Note: PF_RGB == 0
|
|
|
a4bbdd |
0,
|
|
|
d21b46 |
sheet_width );
|
|
trizer |
613172 |
setjmp(png_jmpbuf(png_ptr));
|
|
trizer |
613172 |
png_write_row(png_ptr,buffer);
|
|
trizer |
613172 |
}
|
|
|
e8b33d |
cur_out_image_row = 0;
|
|
|
e8b33d |
if(out_file_pointer)
|
|
trizer |
613172 |
{
|
|
trizer |
613172 |
png_write_end(png_ptr,info_ptr);
|
|
trizer |
613172 |
png_destroy_write_struct(&png_ptr, &info_ptr);
|
|
|
e8b33d |
fclose(out_file_pointer);
|
|
|
e8b33d |
out_file_pointer=NULL;
|
|
trizer |
613172 |
|
|
trizer |
613172 |
}
|
|
trizer |
613172 |
return true;
|
|
Moritz Grosch (LittleFox) |
5352f3 |
}
|