예제 #1
0
파일: instance.cpp 프로젝트: ZurbaXI/synfig
void Instance::save_surface(const synfig::Surface &surface, const synfig::String &filename)
{
	if (surface.get_h() <= 0 || surface.get_w() <= 0) return;

	String ext = filename_extension(filename);
	if (ext.empty()) return;
	ext.erase(0, 1);
	String tmpfile = FileContainerTemporary::generate_temporary_filename();

	etl::handle<Target_Scanline> target
		= etl::handle<Target_Scanline>(Target::create(Target::ext_book()[ext],tmpfile,TargetParam()));
	if (!target) return;
	target->set_canvas(get_canvas());
	RendDesc desc;
	desc.set_w(surface.get_w());
	desc.set_h(surface.get_h());
	desc.set_x_res(1);
	desc.set_y_res(1);
	desc.set_frame_rate(1);
	desc.set_frame(0);
	desc.set_frame_start(0);
	desc.set_frame_end(0);
	target->set_rend_desc(&desc);
	target->add_frame(&surface);
	target = NULL;

	FileSystem::copy(FileSystemNative::instance(), tmpfile, get_file_system(), filename);
	FileSystemNative::instance()->file_remove(tmpfile);
}
예제 #2
0
파일: contour.cpp 프로젝트: d-j-a-y/synfig
void
software::Contour::render_contour(
	synfig::Surface &target_surface,
	const rendering::Contour::ChunkList &chunks,
	bool invert,
	bool antialias,
	rendering::Contour::WindingStyle winding_style,
	const Matrix &transform_matrix,
	const Color &color,
	Color::value_type opacity,
	Color::BlendMethod blend_method )
{
	Polyspan polyspan;
	polyspan.init(0, 0, target_surface.get_w(), target_surface.get_h());
	build_polyspan(chunks, transform_matrix, polyspan);
	polyspan.sort_marks();

	return render_polyspan(
		target_surface,
		polyspan,
		invert,
		antialias,
		winding_style,
		color,
		opacity,
		blend_method );
}
예제 #3
0
void
Action::LayerPaint::PaintStroke::copy_to_cairo_surface(const synfig::Surface &surface, synfig::CairoSurface &csurface)
{
	int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, surface.get_w());
	unsigned char *data = (unsigned char*)malloc(stride * surface.get_h());
	unsigned char *p = data;
	for(int y = 0; y < surface.get_h(); ++y, p += stride)
	{
		CairoColor *c = (CairoColor*)p;
		for(int x = 0; x < surface.get_w(); ++x, ++c)
			*c = CairoColor(surface[y][x]);
	}
	cairo_surface_t *cs = cairo_image_surface_create_for_data(
		data,
		CAIRO_FORMAT_ARGB32,
		surface.get_w(),
		surface.get_h(),
		stride );
	csurface.set_cairo_surface(cs);
	csurface.map_cairo_image();
	cairo_surface_destroy(cs);
}
예제 #4
0
bool
exr_mptr::get_frame(synfig::Surface &out_surface, const synfig::RendDesc &/*renddesc*/, Time, synfig::ProgressCallback *cb)
{
    try
    {

	Imf::RgbaInputFile in(identifier.filename.c_str());

    int w = in.dataWindow().max.x - in.dataWindow().min.x + 1;
    int h = in.dataWindow().max.y - in.dataWindow().min.y + 1;
    //int dx = in.dataWindow().min.x;
    //int dy = in.dataWindow().min.y;

	etl::surface<Imf::Rgba> in_surface;
	in_surface.set_wh(w,h);
	in.setFrameBuffer (reinterpret_cast<Imf::Rgba *>(in_surface[0]), 1, w);

	in.readPixels (in.dataWindow().min.y, in.dataWindow().max.y);

	int x;
	int y;
	out_surface.set_wh(w,h);
	for(y=0;y<out_surface.get_h();y++)
		for(x=0;x<out_surface.get_w();x++)
		{
			Color &color(out_surface[y][x]);
			Imf::Rgba &rgba(in_surface[y][x]);
			color.set_r(rgba.r);
			color.set_g(rgba.g);
			color.set_b(rgba.b);
			color.set_a(rgba.a);
		}
	}
	catch (const std::exception& e)
    {
		if(cb)cb->error(e.what());
		else synfig::error(e.what());
		return false;
    }

	return true;
}
예제 #5
0
bool
bmp_mptr::get_frame(synfig::Surface &surface, const synfig::RendDesc &/*renddesc*/, Time /*time*/, synfig::ProgressCallback *cb)
{
	FILE *file=fopen(filename.c_str(),"rb");
	if(!file)
	{
		if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("Unable to open %s"),filename.c_str()));
		else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("Unable to open %s"),filename.c_str()));
		return false;
	}

	synfig::BITMAPFILEHEADER fileheader;
	synfig::BITMAPINFOHEADER infoheader;
	char b_char=fgetc(file);
	char m_char=fgetc(file);

	if(b_char!='B' || m_char!='M')
	{
		if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("%s is not in BMP format"),filename.c_str()));
		else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("%s is not in BMP format"),filename.c_str()));
		return false;
	}

	if(fread(&fileheader.bfSize, 1, sizeof(synfig::BITMAPFILEHEADER)-4, file)!=sizeof(synfig::BITMAPFILEHEADER)-4)
	{
		String str("bmp_mptr::get_frame(): "+strprintf(_("Failure while reading BITMAPFILEHEADER from %s"),filename.c_str()));
		if(cb)cb->error(str);
		else synfig::error(str);
		return false;
	}

	if(fread(&infoheader, 1, sizeof(synfig::BITMAPINFOHEADER), file)!=sizeof(synfig::BITMAPINFOHEADER))
	{
		String str("bmp_mptr::get_frame(): "+strprintf(_("Failure while reading BITMAPINFOHEADER from %s"),filename.c_str()));
		if(cb)cb->error(str);
		else synfig::error(str);
		return false;
	}

	int offset=little_endian(fileheader.bfOffsetBits);

	if(offset!=sizeof(synfig::BITMAPFILEHEADER)+sizeof(synfig::BITMAPINFOHEADER)-2)
	{
		String str("bmp_mptr::get_frame(): "+strprintf(_("Bad BITMAPFILEHEADER in %s. (bfOffsetBits=%d, should be %d)"),filename.c_str(),offset,sizeof(synfig::BITMAPFILEHEADER)+sizeof(synfig::BITMAPINFOHEADER)-2));
		if(cb)cb->error(str);
		else synfig::error(str);
		return false;
	}

	if(little_endian(infoheader.biSize)!=little_endian(40))
	{
		String str("bmp_mptr::get_frame(): "+strprintf(_("Bad BITMAPINFOHEADER in %s. (biSize=%d, should be 40)"),filename.c_str(),little_endian(infoheader.biSize)));
		if(cb)cb->error(str);
		else synfig::error(str);
		return false;
	}

	int w,h,bit_count;

	w=little_endian(infoheader.biWidth);
	h=little_endian(infoheader.biHeight);
	bit_count=little_endian_short(infoheader.biBitCount);

	synfig::warning("w:%d\n",w);
	synfig::warning("h:%d\n",h);
	synfig::warning("bit_count:%d\n",bit_count);

	if(little_endian(infoheader.biCompression))
	{
		if(cb)cb->error("bmp_mptr::GetFrame(): "+string(_("Reading compressed bitmaps is not supported")));
		else synfig::error("bmp_mptr::GetFrame(): "+string(_("Reading compressed bitmaps is not supported")));
		return false;
	}

	if(bit_count!=24 && bit_count!=32)
	{
		if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("Unsupported bit depth (bit_count=%d, should be 24 or 32)"),bit_count));
		else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("Unsupported bit depth (bit_count=%d, should be 24 or 32)"),bit_count));
		return false;
	}

	int x;
	int y;
	surface.set_wh(w,h);
	for(y=0;y<surface.get_h();y++)
		for(x=0;x<surface.get_w();x++)
		{
//			float b=(float)(unsigned char)fgetc(file)*(1.0/255.0);
//			float g=(float)(unsigned char)fgetc(file)*(1.0/255.0);
//			float r=(float)(unsigned char)fgetc(file)*(1.0/255.0);
			float b=gamma().b_U8_to_F32((unsigned char)fgetc(file));
			float g=gamma().g_U8_to_F32((unsigned char)fgetc(file));
			float r=gamma().r_U8_to_F32((unsigned char)fgetc(file));

			surface[h-y-1][x]=Color(
				r,
				g,
				b,
				1.0
			);
			if(bit_count==32)
				fgetc(file);
		}


	fclose(file);
	return true;
}
예제 #6
0
bool
imagemagick_mptr::get_frame(synfig::Surface &surface, const synfig::RendDesc &renddesc, Time /*time*/, synfig::ProgressCallback *cb)
{
//#define HAS_LIBPNG 1

#if 1
	if(identifier.filename.empty())
	{
		if(cb)cb->error(_("No file to load"));
		else synfig::error(_("No file to load"));
		return false;
	}
	string temp_file="/tmp/deleteme.png";
	string temp_container_file="";

	// todo: "container:" and "images" literals
	if (identifier.filename.substr(0, String("#images/").size())=="#images/")
	{
		temp_container_file = "/tmp/synfigtmp.png";
		// try to copy file to a temp file
		if (!FileSystem::copy(identifier.file_system, identifier.filename, identifier.file_system, temp_container_file))
		{
			if(cb)cb->error(_("Cannot create temporary file of ")+ identifier.filename);
			else synfig::error(_("Cannot create temporary file of ")+ identifier.filename);
			return false;
		}
	}

	string filename = temp_container_file.size() == 0 ? identifier.filename : temp_container_file;

#if defined(WIN32_PIPE_TO_PROCESSES)

	if(file)
		pclose(file);

	string command;

	if(identifier.filename.find("psd")!=String::npos)
		command=strprintf("convert \"%s\" -flatten \"png32:%s\"\n",filename.c_str(),temp_file.c_str());
	else
		command=strprintf("convert \"%s\" \"png32:%s\"\n",filename.c_str(),temp_file.c_str());

	if(system(command.c_str())!=0)
		return false;

#elif defined(UNIX_PIPE_TO_PROCESSES)

	string output="png32:"+temp_file;

	pid_t pid = fork();

	if (pid == -1) {
		return false;
	}

	if (pid == 0){
		// Child process
		if(identifier.filename.find("psd")!=String::npos)
			execlp("convert", "convert", filename.c_str(), "-flatten", output.c_str(), (const char *)NULL);
		else
			execlp("convert", "convert", filename.c_str(), output.c_str(), (const char *)NULL);
		// We should never reach here unless the exec failed
		return false;
	}

	int status;
	waitpid(pid, &status, 0);
	if( (WIFEXITED(status) && WEXITSTATUS(status) != 0) || !WIFEXITED(status) )
		return false;

#else
	#error There are no known APIs for creating child processes
#endif

	//if any delete container tmp file
	if(temp_container_file.size())
		identifier.file_system->file_remove(temp_container_file);

	Importer::Handle importer(Importer::open(synfig::FileSystem::Identifier(synfig::FileSystemNative::instance(), temp_file)));

	if(!importer)
	{
		if(cb)cb->error(_("Unable to open ")+temp_file);
		else synfig::error(_("Unable to open ")+temp_file);
		return false;
	}

	if(!importer->get_frame(surface,renddesc,0,cb))
	{
		if(cb)cb->error(_("Unable to get frame from ")+temp_file);
		else synfig::error(_("Unable to get frame from ")+temp_file);
		return false;
	}

	if(!surface)
	{
		if(cb)cb->error(_("Bad surface from ")+temp_file);
		else synfig::error(_("Bad surface from ")+temp_file);
		return false;
	}

	if(1)
	{
		// remove odd premultiplication
		for(int i=0;i<surface.get_w()*surface.get_h();i++)
		{
			Color c(surface[0][i]);

			if(c.get_a())
			{
				surface[0][i].set_r(c.get_r()/c.get_a()/c.get_a());
				surface[0][i].set_g(c.get_g()/c.get_a()/c.get_a());
				surface[0][i].set_b(c.get_b()/c.get_a()/c.get_a());
			}
			else
			{
				surface[0][i].set_r(0);
				surface[0][i].set_g(0);
				surface[0][i].set_b(0);
			}
			surface[0][i].set_a(c.get_a());
		}
	}

	Surface bleh(surface);
	surface=bleh;

	//remove(temp_file.c_str());
	return true;

#else

#error This code contains tempfile and arbitrary shell command execution vulnerabilities

	if(file)
		pclose(file);

	string command;

	if(identifier.filename.empty())
	{
		if(cb)cb->error(_("No file to load"));
		else synfig::error(_("No file to load"));
		return false;
	}

	command=strprintf("convert \"%s\" -flatten ppm:-\n",identifier.filename.c_str());

	file=popen(command.c_str(),POPEN_BINARY_READ_TYPE);

	if(!file)
	{
		if(cb)cb->error(_("Unable to open pipe to imagemagick"));
		else synfig::error(_("Unable to open pipe to imagemagick"));
		return false;
	}
	int w,h;
	float divisor;
	char cookie[2];

	while((cookie[0]=fgetc(file))!='P' && !feof(file));

	if(feof(file))
	{
		if(cb)cb->error(_("Reached end of stream without finding PPM header"));
		else synfig::error(_("Reached end of stream without finding PPM header"));
		return false;
	}

	cookie[1]=fgetc(file);

	if(cookie[0]!='P' || cookie[1]!='6')
	{
		if(cb)cb->error(string(_("stream not in PPM format"))+" \""+cookie[0]+cookie[1]+'"');
		else synfig::error(string(_("stream not in PPM format"))+" \""+cookie[0]+cookie[1]+'"');
		return false;
	}

	fgetc(file);
	fscanf(file,"%d %d\n",&w,&h);
	fscanf(file,"%f",&divisor);
	fgetc(file);

	if(feof(file))
	{
		if(cb)cb->error(_("Premature end of file (after header)"));
		else synfig::error(_("Premature end of file (after header)"));
		return false;
	}

	int x;
	int y;
	frame.set_wh(w,h);
	for(y=0;y<frame.get_h();y++)
		for(x=0;x<frame.get_w();x++)
		{
			if(feof(file))
			{
				if(cb)cb->error(_("Premature end of file"));
				else synfig::error(_("Premature end of file"));
				return false;
			}
			float b=gamma().r_U8_to_F32((unsigned char)fgetc(file));
			float g=gamma().g_U8_to_F32((unsigned char)fgetc(file));
			float r=gamma().b_U8_to_F32((unsigned char)fgetc(file));
/*
			float b=(float)(unsigned char)fgetc(file)/divisor;
			float g=(float)(unsigned char)fgetc(file)/divisor;
			float r=(float)(unsigned char)fgetc(file)/divisor;
*/
			frame[y][x]=Color(
				b,
				g,
				r,
				1.0
			);
		}

	surface=frame;

	return true;
#endif


}
예제 #7
0
bool
bmp_mptr::get_frame(synfig::Surface &surface, const synfig::RendDesc &/*renddesc*/, Time /*time*/, synfig::ProgressCallback *cb)
{
	FileSystem::ReadStreamHandle stream = identifier.get_read_stream();
	if(!stream)
	{
		if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("Unable to open %s"),identifier.filename.c_str()));
		else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("Unable to open %s"),identifier.filename.c_str()));
		return false;
	}

	synfig::BITMAP::FILEHEADER fileheader;
	synfig::BITMAP::INFOHEADER infoheader;

	if (!stream->read_variable(fileheader.bfType)
	 || fileheader.bfType[0] != 'B'
	 || fileheader.bfType[1] != 'M')
	{
		if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("%s is not in BMP format"),identifier.filename.c_str()));
		else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("%s is not in BMP format"),identifier.filename.c_str()));
		return false;
	}

	if(!stream->read_whole_block(&fileheader.bfSize, sizeof(synfig::BITMAP::FILEHEADER)-2))
	{
		String str("bmp_mptr::get_frame(): "+strprintf(_("Failure while reading BITMAP::FILEHEADER from %s"),identifier.filename.c_str()));
		if(cb)cb->error(str);
		else synfig::error(str);
		return false;
	}

	if(!stream->read_whole_block(&infoheader, sizeof(synfig::BITMAP::INFOHEADER)))
	{
		String str("bmp_mptr::get_frame(): "+strprintf(_("Failure while reading BITMAP::INFOHEADER from %s"),identifier.filename.c_str()));
		if(cb)cb->error(str);
		else synfig::error(str);
		return false;
	}

	int offset=little_endian(fileheader.bfOffsetBits);

	if(offset!=sizeof(synfig::BITMAP::FILEHEADER)+sizeof(synfig::BITMAP::INFOHEADER))
	{
		String str("bmp_mptr::get_frame(): "+strprintf(_("Bad BITMAP::FILEHEADER in %s. (bfOffsetBits=%d, should be %d)"),identifier.filename.c_str(),offset,sizeof(synfig::BITMAP::FILEHEADER)+sizeof(synfig::BITMAP::INFOHEADER)));
		if(cb)cb->error(str);
		else synfig::error(str);
		return false;
	}

	if(little_endian(infoheader.biSize)!=sizeof(synfig::BITMAP::INFOHEADER))
	{
		String str("bmp_mptr::get_frame(): "+strprintf(_("Bad BITMAP::INFOHEADER in %s. (biSize=%d, should be %d)"),identifier.filename.c_str(),little_endian(infoheader.biSize),sizeof(synfig::BITMAP::INFOHEADER)));
		if(cb)cb->error(str);
		else synfig::error(str);
		return false;
	}

	int w,h,bit_count;

	w=little_endian(infoheader.biWidth);
	h=little_endian(infoheader.biHeight);
	bit_count=little_endian_short(infoheader.biBitCount);

	synfig::warning("w:%d\n",w);
	synfig::warning("h:%d\n",h);
	synfig::warning("bit_count:%d\n",bit_count);

	if(little_endian(infoheader.biCompression))
	{
		if(cb)cb->error("bmp_mptr::GetFrame(): "+string(_("Reading compressed bitmaps is not supported")));
		else synfig::error("bmp_mptr::GetFrame(): "+string(_("Reading compressed bitmaps is not supported")));
		return false;
	}

	if(bit_count!=24 && bit_count!=32)
	{
		if(cb)cb->error("bmp_mptr::GetFrame(): "+strprintf(_("Unsupported bit depth (bit_count=%d, should be 24 or 32)"),bit_count));
		else synfig::error("bmp_mptr::GetFrame(): "+strprintf(_("Unsupported bit depth (bit_count=%d, should be 24 or 32)"),bit_count));
		return false;
	}

	int x;
	int y;
	surface.set_wh(w,h);
	for(y=0;y<surface.get_h();y++)
		for(x=0;x<surface.get_w();x++)
		{
//			float b=(float)(unsigned char)stream->getc()*(1.0/255.0);
//			float g=(float)(unsigned char)stream->getc()*(1.0/255.0);
//			float r=(float)(unsigned char)stream->getc()*(1.0/255.0);
			float b=gamma().b_U8_to_F32((unsigned char)stream->get());
			float g=gamma().g_U8_to_F32((unsigned char)stream->get());
			float r=gamma().r_U8_to_F32((unsigned char)stream->get());

			surface[h-y-1][x]=Color(
				r,
				g,
				b,
				1.0
			);
			if(bit_count==32)
				stream->get();
		}


	return true;
}
예제 #8
0
	static inline Color nearest(const synfig::Surface &surface, const Vector &pos)
	{
		return surface[ std::max(std::min((int)floor(pos[1]), surface.get_h()-1), 0) ]
					  [ std::max(std::min((int)floor(pos[0]), surface.get_w()-1), 0) ];
	}