예제 #1
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 );
}
예제 #2
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);
}
예제 #3
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;
}
예제 #4
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);
}
예제 #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
파일: contour.cpp 프로젝트: d-j-a-y/synfig
void
software::Contour::render_polyspan(
	synfig::Surface &target_surface,
	const Polyspan &polyspan,
	bool invert,
	bool antialias,
	rendering::Contour::WindingStyle winding_style,
	const Color &color,
	Color::value_type opacity,
	Color::BlendMethod blend_method )
{
	bool simple_fill = (Color::BLEND_METHODS_OVERWRITE_ON_ALPHA_ONE & (1 << blend_method))
			        && fabsf(1.f - opacity*color.get_a()) <= 1e-6;

	synfig::Surface::alpha_pen p(target_surface.begin(), opacity, blend_method);
	synfig::Surface::pen sp(target_surface.begin());
	const RectInt &window = polyspan.get_window();
	const Polyspan::cover_array &covers = polyspan.get_covers();

	Polyspan::cover_array::const_iterator cur_mark = covers.begin();
	Polyspan::cover_array::const_iterator end_mark = covers.end();

	Real cover = 0, area = 0, alpha = 0;
	int	y = 0, x = 0;

	p.set_value(color);
	sp.set_value(color);
	cover = 0;

	if (cur_mark == end_mark)
	{
		// no marks at all
		if (invert)
		{
			if (simple_fill)
			{
				sp.move_to(window.minx, window.miny);
				sp.put_block(window.maxy - window.miny, window.maxx - window.minx);
			}
			else
			{
				p.move_to(window.minx, window.miny);
				p.put_block(window.maxy - window.miny, window.maxx - window.minx);
			}
		}
		return;
	}

	// fill initial rect / line
	if (invert)
	{
		if (simple_fill)
		{
			// fill all the area above the first vertex
			sp.move_to(window.minx, window.miny);
			y = window.miny;
			int l = window.maxx - window.minx;

			sp.put_block(cur_mark->y - window.miny, l);

			// fill the area to the left of the first vertex on that line
			l = cur_mark->x - window.minx;
			sp.move_to(window.minx, cur_mark->y);
			if (l) sp.put_hline(l);
		}
		else
		{
			// fill all the area above the first vertex
			p.move_to(window.minx, window.miny);
			y = window.miny;
			int l = window.maxx - window.minx;

			p.put_block(cur_mark->y - window.miny, l);

			// fill the area to the left of the first vertex on that line
			l = cur_mark->x - window.minx;
			p.move_to(window.minx, cur_mark->y);
			if (l) p.put_hline(l);
		}
	}

	while(true)
	{
		y = cur_mark->y;
		x = cur_mark->x;

		p.move_to(x,y);

		area = cur_mark->area;
		cover += cur_mark->cover;

		// accumulate for the current pixel
		while(++cur_mark != covers.end())
		{
			if (y != cur_mark->y || x != cur_mark->x)
				break;

			area += cur_mark->area;
			cover += cur_mark->cover;
		}

		// draw pixel - based on covered area
		if (area) // if we're ok, draw the current pixel
		{
			alpha = polyspan.extract_alpha(cover - area, winding_style);
			if (invert) alpha = 1 - alpha;

			if (antialias)
			{
				if (alpha) p.put_value_alpha(alpha);
			}
			else
			{
				if (alpha >= .5) p.put_value();
			}

			p.inc_x();
			++x;
		}

		// if we're done, don't use iterator and exit
		if (cur_mark == end_mark) break;

		// if there is no more live pixels on this line, goto next
		if (y != cur_mark->y)
		{
			if (invert)
			{
				// fill the area at the end of the line
				if (simple_fill)
				{
					sp.move_to(p);
					sp.put_hline(window.maxx - x);
				}
				else
				{
					p.put_hline(window.maxx - x);
				}

				// fill area at the beginning of the next line
				if (simple_fill)
				{
					sp.move_to(window.minx, cur_mark->y);
					sp.put_hline(cur_mark->x - window.minx);
				}
				else
				{
					p.move_to(window.minx, cur_mark->y);
					p.put_hline(cur_mark->x - window.minx);
				}
			}

			cover = 0;
			continue;
		}

		// draw span to next pixel - based on total amount of pixel cover
		if (x < cur_mark->x)
		{
			alpha = polyspan.extract_alpha(cover, winding_style);
			if (invert) alpha = 1 - alpha;
			if (alpha >= .5)
			{
				if (simple_fill)
				{
					sp.move_to(p);
					sp.put_hline(cur_mark->x - x);
					p.move_to(sp);
				}
				else
				{
					p.put_hline(cur_mark->x - x);
				}
			}

			/*
			if (antialias)
			{
				if (alpha) p.put_hline(cur_mark->x - x, alpha);
			}
			else
			{
				if (alpha >= .5) p.put_hline(cur_mark->x - x);
			}
			*/
		}
	}

	// fill the after stuff
	if (invert)
	{
		if (simple_fill)
		{
			sp.move_to(p);

			//fill the area at the end of the line
			sp.put_hline(window.maxx - x);

			//fill area at the beginning of the next line
			sp.move_to(window.minx, y+1);
			sp.put_block(window.maxy - y - 1, window.maxx - window.minx);
		}
		else
		{
			//fill the area at the end of the line
			p.put_hline(window.maxx - x);

			//fill area at the beginning of the next line
			p.move_to(window.minx, y+1);
			p.put_block(window.maxy - y - 1, window.maxx - window.minx);
		}
	}
}
예제 #8
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;
}
예제 #9
0
	static inline Color cubic(const synfig::Surface &surface, const Vector &pos)
		{ return surface.cubic_sample(pos[0] - 0.5, pos[1] - 0.5); }
예제 #10
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) ];
	}
예제 #11
0
bool
mplayer_mptr::get_frame(synfig::Surface &surface, const synfig::RendDesc &renddesc, synfig::Time time, synfig::ProgressCallback *callback)
{

#error This code has vulnerabilites: arbitrary shell command execution and tmpfile issues

	int ret;
	ret=system(
		strprintf("/usr/local/bin/mencoder \"%s\" -ovc rawrgb -ss %f -endpos 0 -nosound -o /tmp/tmp.synfig.rgbdata | grep \"VIDEO\" > /tmp/tmp.synfig.size",
			identifier.filename.c_str(),
			time
		).c_str()
	);
	/*
	if(ret!=0)
	{
		cerr<<"mencoder execution failed."<<endl;
		return false;
	}
*/
	FILE *sizefile=fopen("/tmp/tmp.synfig.size","rt");
	FILE *rgbfile=fopen("/tmp/tmp.synfig.rgbdata","rb");
	if(!rgbfile)
	{
		cerr<<"unable to open /tmp/tmp.synfig.rgbdata"<<endl;
		return false;
	}
	if(!sizefile)
	{
		cerr<<"unable to open /tmp/tmp.synfig.size"<<endl;
		return false;
	}

	int w=4,h=4,x,y;
	char bleh[500];

	fscanf(sizefile,"%499s %499s %dx%d",bleh,bleh,&w,&h);

	cerr<<strprintf("w:%d, h:%d, time:%f",w,h,time)<<endl;
	fseek(rgbfile,2047+3*8,SEEK_CUR);
	surface.set_wh(w,h);
	for(y=0;y<h;y++)
		for(x=0;x<w;x++)
		{
			unsigned char
				b=(unsigned char)fgetc(rgbfile),
				g=(unsigned char)fgetc(rgbfile),
				r=(unsigned char)fgetc(rgbfile);

			surface[h-y-1][x]=Color(
				(float)r/255.0,
				(float)g/255.0,
				(float)b/255.0,
				1.0
			);
		}

	fclose(rgbfile);
	fclose(sizefile);

	return true;
}
예제 #12
0
파일: mptr_png.cpp 프로젝트: synfig/synfig
bool
png_mptr::get_frame(synfig::Surface &surface, const synfig::RendDesc &/*renddesc*/, Time, synfig::ProgressCallback */*cb*/)
{
    /* Open the file pointer */
    FileSystem::ReadStream::Handle stream = identifier.get_read_stream();
    if (!stream)
    {
        //! \todo THROW SOMETHING
        throw strprintf("Unable to physically open %s",identifier.filename.c_str());
        return false;
    }

    /* Make sure we are dealing with a PNG format file */
    png_byte header[PNG_CHECK_BYTES];
    if (!stream->read_variable(header))
    {
        //! \todo THROW SOMETHING
        throw strprintf("Cannot read header from \"%s\"",identifier.filename.c_str());
        return false;
    }

    if (0 != png_sig_cmp(header, 0, PNG_CHECK_BYTES))
    {
        //! \todo THROW SOMETHING
        throw strprintf("This (\"%s\") doesn't appear to be a PNG file",identifier.filename.c_str());
        return false;
    }

    png_structp png_ptr = png_create_read_struct
                          (PNG_LIBPNG_VER_STRING, (png_voidp)this,
                           &png_mptr::png_out_error, &png_mptr::png_out_warning);
    if (!png_ptr)
    {
        //! \todo THROW SOMETHING
        throw String("error on importer construction, *WRITEME*3");
        return false;
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_read_struct(&png_ptr,
                                (png_infopp)NULL, (png_infopp)NULL);
        //! \todo THROW SOMETHING
        throw String("error on importer construction, *WRITEME*4");
        return false;
    }

    png_infop end_info = png_create_info_struct(png_ptr);
    if (!end_info)
    {
        png_destroy_read_struct(&png_ptr, &info_ptr,
                                (png_infopp)NULL);
        //! \todo THROW SOMETHING
        throw String("error on importer construction, *WRITEME*4");
        return false;
    }

    png_set_read_fn(png_ptr, stream.get(), read_callback);
    png_set_sig_bytes(png_ptr,PNG_CHECK_BYTES);

    png_read_info(png_ptr, info_ptr);

    int bit_depth,color_type,interlace_type, compression_type,filter_method;
    png_uint_32 width,height;

    png_get_IHDR(png_ptr, info_ptr, &width, &height,
                 &bit_depth, &color_type, &interlace_type,
                 &compression_type, &filter_method);

    if (bit_depth == 16)
        png_set_strip_16(png_ptr);

    if (bit_depth < 8)
        png_set_packing(png_ptr);

    double fgamma;
    if (png_get_gAMA(png_ptr, info_ptr, &fgamma))
    {
        synfig::info("PNG: Image gamma is %f",fgamma);
        png_set_gamma(png_ptr, gamma().get_gamma(), fgamma);
    }


    /*
    if (setjmp(png_jmpbuf(png_ptr)))
    {
    	synfig::error("Unable to setup longjump");
    	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    	fclose(file);
        //! \todo THROW SOMETHING
    	throw String("error on importer construction, *WRITEME*5");
    	return;
    }
    */

    // man libpng tells me:
    //   You must use png_transforms and not call any
    //   png_set_transform() functions when you use png_read_png().
    // but we used png_set_gamma(), which may be why we were seeing a crash at the end
    //   png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING|PNG_TRANSFORM_STRIP_16, NULL);

    png_read_update_info(png_ptr, info_ptr);
    png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr);

    // allocate buffer to read image data into
    png_bytep *row_pointers=new png_bytep[height];
    png_byte *data = new png_byte[rowbytes*height];
    for (png_uint_32 i = 0; i < height; i++)
        row_pointers[i] = &(data[rowbytes*i]);

    png_read_image(png_ptr, row_pointers);

    png_uint_32 x, y;
    surface.set_wh(width,height);

    switch(color_type)
    {
    case PNG_COLOR_TYPE_RGB:
        for(y=0; y<height; y++)
            for(x=0; x<width; x++)
            {
                float r=gamma().r_U8_to_F32((unsigned char)row_pointers[y][x*3+0]);
                float g=gamma().g_U8_to_F32((unsigned char)row_pointers[y][x*3+1]);
                float b=gamma().b_U8_to_F32((unsigned char)row_pointers[y][x*3+2]);
                surface[y][x]=Color(
                                  r,
                                  g,
                                  b,
                                  1.0
                              );
                /*
                				surface[y][x]=Color(
                					(float)(unsigned char)row_pointers[y][x*3+0]*(1.0/255.0),
                					(float)(unsigned char)row_pointers[y][x*3+1]*(1.0/255.0),
                					(float)(unsigned char)row_pointers[y][x*3+2]*(1.0/255.0),
                					1.0
                				);
                */
            }
        break;

    case PNG_COLOR_TYPE_RGB_ALPHA:
        for(y=0; y<height; y++)
            for(x=0; x<width; x++)
            {
                float r=gamma().r_U8_to_F32((unsigned char)row_pointers[y][x*4+0]);
                float g=gamma().g_U8_to_F32((unsigned char)row_pointers[y][x*4+1]);
                float b=gamma().b_U8_to_F32((unsigned char)row_pointers[y][x*4+2]);
                surface[y][x]=Color(
                                  r,
                                  g,
                                  b,
                                  (float)(unsigned char)row_pointers[y][x*4+3]*(1.0/255.0)
                              );
                /*
                surface[y][x]=Color(
                	(float)(unsigned char)row_pointers[y][x*4+0]*(1.0/255.0),
                	(float)(unsigned char)row_pointers[y][x*4+1]*(1.0/255.0),
                	(float)(unsigned char)row_pointers[y][x*4+2]*(1.0/255.0),
                	(float)(unsigned char)row_pointers[y][x*4+3]*(1.0/255.0)
                );
                */
            }
        break;

    case PNG_COLOR_TYPE_GRAY:
        for(y=0; y<height; y++)
            for(x=0; x<width; x++)
            {
                float gray=gamma().g_U8_to_F32((unsigned char)row_pointers[y][x]);
                //float gray=(float)(unsigned char)row_pointers[y][x]*(1.0/255.0);
                surface[y][x]=Color(
                                  gray,
                                  gray,
                                  gray,
                                  1.0
                              );
            }
        break;

    case PNG_COLOR_TYPE_GRAY_ALPHA:
        for(y=0; y<height; y++)
            for(x=0; x<width; x++)
            {
                float gray=gamma().g_U8_to_F32((unsigned char)row_pointers[y][x*2]);
//				float gray=(float)(unsigned char)row_pointers[y][x*2]*(1.0/255.0);
                surface[y][x]=Color(
                                  gray,
                                  gray,
                                  gray,
                                  (float)(unsigned char)row_pointers[y][x*2+1]*(1.0/255.0)
                              );
            }
        break;

    case PNG_COLOR_TYPE_PALETTE:
    {
        png_colorp palette;
        int num_palette;
        png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
        png_bytep trans_alpha = NULL;
        int num_trans = 0;
        bool has_alpha = (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans,
                                       NULL) & PNG_INFO_tRNS);
        for(y=0; y<height; y++)
            for(x=0; x<width; x++)
            {
                float r=gamma().r_U8_to_F32((unsigned char)palette[row_pointers[y][x]].red);
                float g=gamma().g_U8_to_F32((unsigned char)palette[row_pointers[y][x]].green);
                float b=gamma().b_U8_to_F32((unsigned char)palette[row_pointers[y][x]].blue);
                float a=1.0;

                if (has_alpha && num_trans > 0 && trans_alpha != NULL)
                {
                    a = row_pointers[y][x] < num_trans ?
                        (trans_alpha[row_pointers[y][x]]*(1.0/255.0)) : 1.0;
                }

                surface[y][x]=Color(
                                  r,
                                  g,
                                  b,
                                  a
                              );
            }
        break;
    }
    default:
        png_read_end(png_ptr, end_info);
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        synfig::error("png_mptr: error: Unsupported color type");
        //! \todo THROW SOMETHING
        throw String("error on importer construction, *WRITEME*6");
        return false;
    }

    png_read_end(png_ptr, end_info);
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);

    return true;
}