Example #1
0
/// <summary>
/// Save the current render results to a file.
/// This could benefit from QImageWriter, however its compression capabilities are
/// severely lacking. A Png file comes out larger than a bitmap, so instead use the
/// Png and Jpg wrapper functions from the command line programs.
/// This will embed the id, url and nick fields from the options in the image comments.
/// </summary>
/// <param name="filename">The full path and filename</param>
/// <param name="comments">The comments to save in the png or jpg</param>
/// <param name="pixels">The buffer containing the pixels</param>
/// <param name="width">The width in pixels of the image</param>
/// <param name="height">The height in pixels of the image</param>
/// <param name="channels">The number of channels, 3 or 4.</param>
/// <param name="bpc">The bytes per channel, almost always 1.</param>
void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<byte>& pixels, size_t width, size_t height, size_t channels, size_t bpc)
{
	if (filename != "")
	{
		bool b = false;
		uint i, j;
		byte* data = nullptr;
		vector<byte> vecRgb;
		QFileInfo fileInfo(filename);
		QString suffix = fileInfo.suffix();
		FractoriumSettings* settings = m_Fractorium->m_Settings;
		
		//Ensure dimensions are valid.
		if (pixels.size() < (width * height * channels * bpc))
		{
			m_Fractorium->ShowCritical("Save Failed", "Dimensions didn't match, not saving.", true);
			return;
		}

		data = pixels.data();//Png and channels == 4.
		
		if ((suffix == "jpg" || suffix == "bmp") && channels)
		{
			RgbaToRgb(pixels, vecRgb, width, height);
			
			data = vecRgb.data();
		}
		
		string s = filename.toStdString();
		string id = settings->Id().toStdString();
		string url = settings->Url().toStdString();
		string nick = settings->Nick().toStdString();

		if (suffix == "png")
			b = WritePng(s.c_str(), data, width, height, 1, true, comments, id, url, nick);
		else if (suffix == "jpg")
			b = WriteJpeg(s.c_str(), data, width, height, 100, true, comments, id, url, nick);
		else if (suffix == "bmp")
			b = WriteBmp(s.c_str(), data, width, height);
		else
		{
			m_Fractorium->ShowCritical("Save Failed", "Unrecognized format " + suffix + ", not saving.", true);
			return;
		}

		if (b)
			settings->SaveFolder(fileInfo.canonicalPath());
		else
			m_Fractorium->ShowCritical("Save Failed", "Could not save file, try saving to a different folder.", true);
	}
}
Example #2
0
void main()
{
	int fmode=0;
	int i,j;
	int red[256];
	int green[256];
	int blue[256];

	FILE *f;

	
	char *filename="text_gray.bmp";
	
	ReadBmp(filename,&tmp1);
	
	printf("%d %d\n",tmp1.height,tmp1.width);
	
	while(1){
	
		printf(" 0:モード法\n 1:判別分析法\n 2:移動平均法\n 3:終了\n");
		scanf("%d",&fmode);
		
		if(fmode > 2) break;
		
		tmp2=tmp1;     /* 元の画像ファイルのすべての画像データをコピーする */
	
		reset( red, green, blue );
	
		Gray( &tmp2 , &tmp1 );
	
		set( red , green , blue );
	
		switch(fmode){
			case 0 : mode(red);		//モード法
					 break;
			case 1 : sweep(red);	//判別分析法
					 break;
			case 2 : mov_ave(red);	//移動平均法
					 break;
		}
	WriteBmp("border.bmp",&tmp2);
	
	PrintBmpInfo("border.bmp");
	}
}
Example #3
0
void Renderer::RenderEuler3D( float* d, int N, int frame, 
	const char* filename, int width, int height )
{
	// Eye Position
	const float eyePos[3] = { 0.5, 0.5, -1.0 };

	// Light Position
	const float lightPos[3] = { 0.5, 1.5, 0.2 };

	// Light Intensity
	const float lightIntensity = 8.0;

	// Absortion
	const float absorption = 11.0;

	// Ray Samples
	const int numSamples = 128;

	// Ray Light Samples
	const int numLightSample = 64;

	// Maximum Distance
	const float maxDist = 3.0;

	// Ray Sampling Space
	const float stride = maxDist/numSamples;

	// Light Ray Sampling Space
	const float lstride = maxDist/numLightSample;

	// Memory Allocation
	static unsigned char *image = new unsigned char[width*height*4];

	for( int ci=0; ci<width*height; ci++ ) { 
		int i=ci%width; int j=ci/width;
		// Transmittance
		float T = 1.0;

		// In-scattered Radiance
		float Lo = 0.0;

		// Pixel Position
		float pixPos[3] = {i/(float)width,j/(float)height};

		// Eye Vector
		float eyeVec[3] = {pixPos[0]-eyePos[0],pixPos[1]-eyePos[1],pixPos[2]-eyePos[2]};
		normalize(eyeVec);

		// Sphere Hit
		bool hitSphere = false;
		float dotProduct = 0.0;

		// Sample Density...
		for( int n=0; n<numSamples; n++ ) {

			// Sample Point
			float pos[3] = { eyePos[0]+stride*n*eyeVec[0], eyePos[1]+stride*n*eyeVec[1], eyePos[2]+stride*n*eyeVec[2] };

			// Sample Density
			float density = sample3D(d, N, pos);

			// Skip Empty Density
			if( density > 0.0 ) {

				// Attenuate
				T *= 1.0-density*stride*absorption;
				if( T <= 0.01 ) break;

				// Compute Light Ray
				float lightVec[3] = {lightPos[0]-pos[0],lightPos[1]-pos[1],lightPos[2]-pos[2]};
				normalize(lightVec);

				// Transmittance Along Light Ray
				float Tl = 1.0;

				// Sample Density Again...
				for( int m=1; m<numLightSample; m++ ) {

					// Sample Point
					float lpos[3] = { pos[0]+lstride*m*lightVec[0], pos[1]+lstride*m*lightVec[1], pos[2]+lstride*m*lightVec[2] };

					// Sample Density
					float ldensity = sample3D(d, N, lpos);

					// Attenuate
					Tl *= 1.0-absorption*lstride*ldensity;
					if( Tl <= 0.01 ) break;
				}

				float Li = lightIntensity*Tl;
				Lo += Li*T*density*stride;
			}
		}

		// At Floor
		float Tf = 0.0;
		if( eyeVec[1] < 0.0 && hitSphere == false ) {
			float flen = -pixPos[1]/eyeVec[1];
			Tf = exp(-0.3*flen);

			// Compute Floor Intersection
			float pos[3] = {pixPos[0]+flen*eyeVec[0],pixPos[1]+flen*eyeVec[1],pixPos[2]+flen*eyeVec[2]};

			// Compute Light Ray
			float lightVec[3] = {lightPos[0]-pos[0],lightPos[1]-pos[1],lightPos[2]-pos[2]};
			normalize(lightVec);

			// Sample Density
			for( int m=1; m<numLightSample; m++ ) {

				// Sample Point
				float lpos[3] = { pos[0]+lstride*m*lightVec[0], pos[1]+lstride*m*lightVec[1], pos[2]+lstride*m*lightVec[2] };

				// Sample Density
				float ldensity = sample3D(d, N, lpos);

				// Attenuate
				Tf *= 1.0-0.5*absorption*lstride*ldensity;
				if( Tf <= 0.01 ) break;
			}
		}

		// Floor Color
		unsigned char floor_color[3] = { 75, 60, 45 };

		// Sphere Color
		unsigned char sphere_color[3] = { 50, 100, 150 };

		for( int k=0; k<3; k++ ) {
			image[4*(i+j*width)+k] = max(0,min(255,255*Lo + T*(Tf*floor_color[k] + dotProduct*sphere_color[k])));
		}
	}

	char fn[128];
	sprintf(fn, "%s_%d.bmp", filename, frame );
	WriteBmp(fn, image, width, height, false );
}
Example #4
0
bool EmberRender(EmberOptions& opt)
{
#ifdef USECL	EmberCLns::OpenCLInfo& info(EmberCLns::OpenCLInfo::Instance());#endif
	std::cout.imbue(std::locale(""));

	if (opt.DumpArgs())
		cout << opt.GetValues(OPT_USE_RENDER) << endl;

	if (opt.OpenCLInfo())
	{
		cout << "\nOpenCL Info: " << endl;
		cout << info.DumpInfo();
		return true;
	}

	Timing t;
	bool writeSuccess = false;
	byte* finalImagep;
	uint padding;
	size_t i, channels;
	size_t strips;
	size_t iterCount;
	string filename;
	string inputPath = GetPath(opt.Input());
	ostringstream os;
	pair<size_t, size_t> p;
	vector<Ember<T>> embers;
	vector<byte> finalImage;
	EmberStats stats;
	EmberReport emberReport;
	EmberImageComments comments;
	XmlToEmber<T> parser;
	EmberToXml<T> emberToXml;
	vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>> randVec;
	const vector<pair<size_t, size_t>> devices = Devices(opt.Devices());
	unique_ptr<RenderProgress<T>> progress(new RenderProgress<T>());
	unique_ptr<Renderer<T, float>> renderer(CreateRenderer<T>(opt.EmberCL() ? OPENCL_RENDERER : CPU_RENDERER, devices, false, 0, emberReport));
	vector<string> errorReport = emberReport.ErrorReport();

	if (!errorReport.empty())
		emberReport.DumpErrorReport();

	if (!renderer.get())
	{
		cout << "Renderer creation failed, exiting." << endl;
		return false;
	}

	if (opt.EmberCL() && renderer->RendererType() != OPENCL_RENDERER)//OpenCL init failed, so fall back to CPU.
		opt.EmberCL(false);

	if (!InitPaletteList<T>(opt.PalettePath()))
		return false;

	if (!ParseEmberFile(parser, opt.Input(), embers))
		return false;

	if (!opt.EmberCL())
	{
		if (opt.ThreadCount() == 0)
		{
			cout << "Using " << Timing::ProcessorCount() << " automatically detected threads." << endl;
			opt.ThreadCount(Timing::ProcessorCount());
		}
		else
		{
			cout << "Using " << opt.ThreadCount() << " manually specified threads." << endl;
		}

		renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr);
	}
	else
	{
		cout << "Using OpenCL to render." << endl;

		if (opt.Verbose())
		{
			for (auto& device : devices)
			{
				cout << "Platform: " << info.PlatformName(device.first) << endl;
				cout << "Device: " << info.DeviceName(device.first, device.second) << endl;
			}
		}

		if (opt.ThreadCount() > 1)
			cout << "Cannot specify threads with OpenCL, using 1 thread." << endl;

		opt.ThreadCount(1);
		renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr);

		if (opt.BitsPerChannel() != 8)
		{
			cout << "Bits per channel cannot be anything other than 8 with OpenCL, setting to 8." << endl;
			opt.BitsPerChannel(8);
		}
	}

	if (opt.Format() != "jpg" &&
		opt.Format() != "png" &&
		opt.Format() != "ppm" &&
		opt.Format() != "bmp")
	{
		cout << "Format must be jpg, png, ppm, or bmp not " << opt.Format() << ". Setting to jpg." << endl;
	}

	channels = opt.Format() == "png" ? 4 : 3;

	if (opt.BitsPerChannel() == 16 && opt.Format() != "png")
	{
		cout << "Support for 16 bits per channel images is only present for the png format. Setting to 8." << endl;
		opt.BitsPerChannel(8);
	}
	else if (opt.BitsPerChannel() != 8 && opt.BitsPerChannel() != 16)
	{
		cout << "Unexpected bits per channel specified " << opt.BitsPerChannel() << ". Setting to 8." << endl;
		opt.BitsPerChannel(8);
	}

	if (opt.InsertPalette() && opt.BitsPerChannel() != 8)
	{
		cout << "Inserting palette only supported with 8 bits per channel, insertion will not take place." << endl;
		opt.InsertPalette(false);
	}

	if (opt.AspectRatio() < 0)
	{
		cout << "Invalid pixel aspect ratio " << opt.AspectRatio() << endl << ". Must be positive, setting to 1." << endl;
		opt.AspectRatio(1);
	}

	if (!opt.Out().empty() && (embers.size() > 1))
	{
		cout << "Single output file " << opt.Out() << " specified for multiple images. Changing to use prefix of badname-changethis instead. Always specify prefixes when reading a file with multiple embers." << endl;
		opt.Out("");
		opt.Prefix("badname-changethis");
	}

	//Final setup steps before running.
	os.imbue(std::locale(""));
	padding = uint(std::log10(double(embers.size()))) + 1;
	renderer->EarlyClip(opt.EarlyClip());
	renderer->YAxisUp(opt.YAxisUp());
	renderer->LockAccum(opt.LockAccum());
	renderer->InsertPalette(opt.InsertPalette());
	renderer->PixelAspectRatio(T(opt.AspectRatio()));
	renderer->Transparency(opt.Transparency());
	renderer->NumChannels(channels);
	renderer->BytesPerChannel(opt.BitsPerChannel() / 8);
	renderer->Priority(eThreadPriority(Clamp<intmax_t>(intmax_t(opt.Priority()), intmax_t(eThreadPriority::LOWEST), intmax_t(eThreadPriority::HIGHEST))));
	renderer->Callback(opt.DoProgress() ? progress.get() : nullptr);

	for (i = 0; i < embers.size(); i++)
	{
		if (opt.Verbose() && embers.size() > 1)
			cout << "\nFlame = " << i + 1 << "/" << embers.size() << endl;
		else if (embers.size() > 1)
			VerbosePrint(endl);

		if (opt.Supersample() > 0)
			embers[i].m_Supersample = opt.Supersample();

		if (opt.SubBatchSize() != DEFAULT_SBS)
			embers[i].m_SubBatchSize = opt.SubBatchSize();

		embers[i].m_TemporalSamples = 1;//Force temporal samples to 1 for render.
		embers[i].m_Quality *= T(opt.QualityScale());
		embers[i].m_FinalRasW = size_t(T(embers[i].m_FinalRasW) * opt.SizeScale());
		embers[i].m_FinalRasH = size_t(T(embers[i].m_FinalRasH) * opt.SizeScale());
		embers[i].m_PixelsPerUnit *= T(opt.SizeScale());

		if (embers[i].m_FinalRasW == 0 || embers[i].m_FinalRasH == 0)
		{
			cout << "Output image " << i << " has dimension 0: " << embers[i].m_FinalRasW  << ", " << embers[i].m_FinalRasH << ". Setting to 1920 x 1080." << endl;
			embers[i].m_FinalRasW = 1920;
			embers[i].m_FinalRasH = 1080;
		}

		//Cast to double in case the value exceeds 2^32.
		double imageMem = double(renderer->NumChannels()) * double(embers[i].m_FinalRasW)
			   * double(embers[i].m_FinalRasH) * double(renderer->BytesPerChannel());
		double maxMem = pow(2.0, double((sizeof(void*) * 8) - 1));

		if (imageMem > maxMem)//Ensure the max amount of memory for a process is not exceeded.
		{
			cout << "Image " << i << " size > " << maxMem << ". Setting to 1920 x 1080." << endl;
			embers[i].m_FinalRasW = 1920;
			embers[i].m_FinalRasH = 1080;
		}

		stats.Clear();
		renderer->SetEmber(embers[i]);
		renderer->PrepFinalAccumVector(finalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run().

		if (opt.Strips() > 1)
		{
			strips = opt.Strips();
		}
		else
		{
			p = renderer->MemoryRequired(1, true, false);//No threaded write for render, only for animate.
			strips = CalcStrips(double(p.second), double(renderer->MemoryAvailable()), opt.UseMem());

			if (strips > 1)
				VerbosePrint("Setting strips to " << strips << " with specified memory usage of " << opt.UseMem());
		}

		strips = VerifyStrips(embers[i].m_FinalRasH, strips,
			[&](const string& s) { cout << s << endl; },//Greater than height.
			[&](const string& s) { cout << s << endl; },//Mod height != 0.
			[&](const string& s) { cout << s << endl; });//Final strips value to be set.

		//For testing incremental renderer.
		//int sb = 1;
		//bool resume = false, success = false;
		//do
		//{
		//	success = renderer->Run(finalImage, 0, sb, false/*resume == false*/) == RENDER_OK;
		//	sb++;
		//	resume = true;
		//}
		//while (success && renderer->ProcessState() != ACCUM_DONE);

		StripsRender<T>(renderer.get(), embers[i], finalImage, 0, strips, opt.YAxisUp(),
		[&](size_t strip)//Pre strip.
		{
			if (opt.Verbose() && (strips > 1) && strip > 0)
				cout << endl;

			if (strips > 1)
				VerbosePrint("Strip = " << (strip + 1) << "/" << strips);
		},
		[&](size_t strip)//Post strip.
		{
			progress->Clear();
			stats += renderer->Stats();
		},
		[&](size_t strip)//Error.
		{
			cout << "Error: image rendering failed, skipping to next image." << endl;
			renderer->DumpErrorReport();//Something went wrong, print errors.
		},
		//Final strip.
		//Original wrote every strip as a full image which could be very slow with many large images.
		//Only write once all strips for this image are finished.
		[&](Ember<T>& finalEmber)
		{
			if (!opt.Out().empty())
			{
				filename = opt.Out();
			}
			else if (opt.NameEnable() && !finalEmber.m_Name.empty())
			{
				filename = inputPath + opt.Prefix() + finalEmber.m_Name + opt.Suffix() + "." + opt.Format();
			}
			else
			{
				ostringstream fnstream;

				fnstream << inputPath << opt.Prefix() << setfill('0') << setw(padding) << i << opt.Suffix() << "." << opt.Format();
				filename = fnstream.str();
			}

			//TotalIterCount() is actually using ScaledQuality() which does not get reset upon ember assignment,
			//so it ends up using the correct value for quality * strips.
			iterCount = renderer->TotalIterCount(1);
			comments = renderer->ImageComments(stats, opt.PrintEditDepth(), opt.IntPalette(), opt.HexPalette());
			os.str("");
			os << comments.m_NumIters << " / " << iterCount << " (" << std::fixed << std::setprecision(2) << ((double(stats.m_Iters) / double(iterCount)) * 100) << "%)";

			VerbosePrint("\nIters ran/requested: " + os.str());
			if (!opt.EmberCL()) VerbosePrint("Bad values: " << stats.m_Badvals);
			VerbosePrint("Render time: " + t.Format(stats.m_RenderMs));
			VerbosePrint("Pure iter time: " + t.Format(stats.m_IterMs));
			VerbosePrint("Iters/sec: " << size_t(stats.m_Iters / (stats.m_IterMs / 1000.0)) << endl);
			VerbosePrint("Writing " + filename);

			if ((opt.Format() == "jpg" || opt.Format() == "bmp") && renderer->NumChannels() == 4)
				RgbaToRgb(finalImage, finalImage, renderer->FinalRasW(), renderer->FinalRasH());

			finalImagep = finalImage.data();
			writeSuccess = false;

			if (opt.Format() == "png")
				writeSuccess = WritePng(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.BitsPerChannel() / 8, opt.PngComments(), comments, opt.Id(), opt.Url(), opt.Nick());
			else if (opt.Format() == "jpg")
				writeSuccess = WriteJpeg(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, int(opt.JpegQuality()), opt.JpegComments(), comments, opt.Id(), opt.Url(), opt.Nick());
			else if (opt.Format() == "ppm")
				writeSuccess = WritePpm(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH);
			else if (opt.Format() == "bmp")
				writeSuccess = WriteBmp(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH);

			if (!writeSuccess)
				cout << "Error writing " << filename << endl;
		});

		if (opt.EmberCL() && opt.DumpKernel())
		{
			if (auto rendererCL = dynamic_cast<RendererCL<T, float>*>(renderer.get()))
			{
				cout << "Iteration kernel:\n" <<
				rendererCL->IterKernel() << "\n\n" <<
				"Density filter kernel:\n" <<
				rendererCL->DEKernel() << "\n\n" <<
				"Final accumulation kernel:\n" <<
				rendererCL->FinalAccumKernel() << endl;
			}
		}

		VerbosePrint("Done.");
	}

	t.Toc("\nFinished in: ", true);

	return true;
}
Example #5
0
bool Encryption(char *file_in_name){
	//初期化
	char *file_out_name;//画像の出力・入力ファイル名
	char *key_out_file;//鍵ファイル
	char *buf;
	img *imagein, *imageout;
	int h, w;
	int i = 0;
	int registered_num = 0;//色の登録数
	angou *code;//色を変換するテーブル
	FILE* fp;

	srand((unsigned)time(NULL));
	file_out_name = (char *)malloc(sizeof(char)*(strlen(file_in_name) + 10));
	strcpy(file_out_name, file_in_name);
	strcat(file_out_name, "_conv.bmp");
	key_out_file = (char *)malloc(sizeof(char)*(strlen(file_in_name) + 8));
	buf = (char *)malloc(sizeof(char)*(strlen(file_in_name) + 1));
	strcpy(buf, file_in_name);
	strcpy(key_out_file, buf);
	strcat(key_out_file, "_key.kp");
	imagein = (img *)malloc(sizeof(img));
	imageout = (img *)malloc(sizeof(img));
	ReadBmp(file_in_name, imagein);
	code = (angou *)malloc(sizeof(angou)*imagein->height*imagein->width);
	imageout = imagein;
	if ((fp = fopen(key_out_file, "w")) == NULL){
		MessageBox(NULL, TEXT("key file output error."), NULL, MB_OK);
		return false;
	}

	//画像処理  
	for (h = 0; h < imagein->height; h++){
		for (w = 0; w < imagein->width; w++){
			for (i = 0; i <= registered_num; i++){
				if (memcmp(&code[i].original_color,
					&imagein->data[h][w],
					sizeof(code[i].original_color)) == 0){
					//登録してある色が見つかったら代入
					imageout->data[h][w] = code[i].converted_color;
					goto searched_out;
				}
			}

			//変換する色の登録
			//変換前の色を登録
			code[registered_num].original_color = imagein->data[h][w];
		try_again:
			//変換後の色を登録
			code[registered_num].converted_color.r = rand() % 256;
			code[registered_num].converted_color.g = rand() % 256;
			code[registered_num].converted_color.b = rand() % 256;
			///*変換後の色が既に登録してある色だったら
			// 変換後の色の登録をやり直す*/
			for (i = 0; i < registered_num; i++){
				if (memcmp(&code[registered_num].converted_color,
					&code[i].converted_color,
					sizeof(code[registered_num].converted_color)) == 0){
					goto try_again;
				}
			}
			//出力画像に変換後の色を代入
			imageout->data[h][w] = code[registered_num].converted_color;
			registered_num++;
		searched_out:
			;
		}
	}
	fwrite(code, sizeof(angou), registered_num, fp);//鍵ファイルに変換情報を記録
	WriteBmp(file_out_name, imageout);

	//後処理  
	fclose(fp);
	//free(file_out_name);
	/*free(key_out_file);*/ free(buf);
	free(code);
	return true;
}