<?php
	//////////////////////////////////////////////////////////////////////////
	//									//
	//   Rafael Páez - @fikih888  						//
	//   LSB - Least Significant Bit (1/3)					//
	//   Script que permite ocultar un fichero en una imagen mediante LSB	//
	//									//
	//////////////////////////////////////////////////////////////////////////

	function bit_oculto ($bit_oculto,$bit_color)
	{
		if($bit_oculto==1)
		{
			$new_bit=$bit_color | 0x01;
		}
		else 
		{
			$new_bit=$bit_color & 0xFE;
		}
		return $new_bit;
	}


	if($argc!=6)
	{
		echo "\n  Modo de empleo: ocultar.php formato_entrada[jpeg/png] recorrido[filas/columnas] imagen_portadora fichero_a_ocultar imagen_resultante\n\n";
	}
	else
	{
		//Obtenemos los argumentos
		$tipo_imagen=$argv[1];
		$recorrido=$argv[2];
		$nombre_portadora=$argv[3];
		$nombre_fichero_ocultar=$argv[4];
		$nombre_salida=$argv[5];
		$nombre_binario="bin_aux";

		if($tipo_imagen != "jpeg" && $tipo_imagen != "png")
		{
			echo "  El formato de la imagen de entrada no es correcto! Especifica \"jpeg\" o \"png\".\n\n";
		}
		else if($recorrido != "filas" && $recorrido != "columnas")
		{
			echo "  El tipo de recorrido no es correcto! Especifica \"filas\" o \"columnas\".\n\n";
		}
		else
		{
			//////
			// Creamos el fichero binario auxiliar que contiene los bits del archivo a ocultar

			echo "\n  Procesando........\n";

			$archivo_ocultar=fopen($nombre_fichero_ocultar, "r");
			$archivo_binario=fopen($nombre_binario, "w");
			$contador=0;

			while(!feof($archivo_ocultar)) 
			{
				//obtenemos 1 byte del archivo a ocultar
				$byte = fread($archivo_ocultar, 1);
				if(strlen($byte)!=0)
				{
					$bin_total="";
					$byte_ascii=ord("$byte");

					//bucle para pasar el byte obtenido a binario
					for($i=7;$i>=0;$i-=1)
					{
						$x_dec=($byte_ascii >> $i) & 0x01;	
						$bin_total.=$x_dec;
						$contador+=1;
					}		
					fputs($archivo_binario, $bin_total);
				}
			}

			fclose($archivo_binario);
			fclose($archivo_ocultar);


			/////////////////////
			// Procedemos a ocultar el archivo en la imagen

			$archivo_binario=fopen($nombre_binario,"r");
			if($tipo_imagen=="jpeg")
			{
				$archivo_imagen=imagecreatefromjpeg("$nombre_portadora");
			}
			else
			{
				$archivo_imagen=imagecreatefrompng("$nombre_portadora");
			}
				
			//Comprobamos que se pueda usar el método LSB en los archivos seleccionados
			$num_bits_imagen=imagesx($archivo_imagen)*imagesy($archivo_imagen)*3;
			if($contador > ($num_bits_imagen))
			{
				echo "\n\n  Error! El archivo es demasiado grande para ocultarlo en la imagen seleccionada.\n\n";
				echo "  Bits archivo a ocultar: $contador\n";
				echo "  Bits útiles en la imagen portadora: $num_bits_imagen\n";
			}
 			else
			{
				echo "  Ocultando.........\n";
				$imagen_nueva=ImageCreatetruecolor(imagesx($archivo_imagen), imagesy($archivo_imagen)); 

				if($recorrido=="filas")
				{	
					$xmax=imagesx($archivo_imagen);
					$ymax=imagesy($archivo_imagen);
				}
				else
				{
					$xmax=imagesy($archivo_imagen);
					$ymax=imagesx($archivo_imagen);
				}


				//Recorremos todos los pixeles de la imagen portadora por filas/columnas
				for($y=0;$y<$ymax;$y++)
				{
					for($x=0;$x<$xmax;$x++)
					{
						//Obtenemos el color rgb del pixel
						if($recorrido=="filas")
						{
							$rgb=imagecolorat($archivo_imagen, $x, $y);
						}
						else
						{
							$rgb=imagecolorat($archivo_imagen, $y, $x);
						}
						 
						//Obtenemos cada color por separado
						$r=($rgb >> 16) & 0xFF; 
						$g=($rgb >> 8) & 0xFF;  
						$b=$rgb & 0xFF;         

						//obtenemos 3 bits del archivo a ocultar
						$byte=fread($archivo_binario, 3);
						if(strlen($byte)!=0)
						{
							//Introducimos los bits a ocultar
							$bit_r_oculto=substr($byte,0,1);
							$bit_g_oculto=substr($byte,1,1);
							$bit_b_oculto=substr($byte,2,1);

							$rnew=bit_oculto($bit_r_oculto,$r);
							$gnew=bit_oculto($bit_g_oculto,$g);
							$bnew=bit_oculto($bit_b_oculto,$b);
						}
						else
						{
							//Introducimos los bits a ocultar 0
							$rnew=$r & 0xFE;
							$gnew=$g & 0xFE;
							$bnew=$b & 0xFE;
						}

						//Creamos el rgb nuevo
						$rgbnew = ($rnew << 16);
						$rgbnew = $rgbnew | ($gnew << 8);
						$rgbnew = $rgbnew | $bnew;

						//pintamos el pixel
						if($recorrido=="filas")
						{
							Imagesetpixel($imagen_nueva,$x,$y,$rgbnew);
						}
						else
						{
							Imagesetpixel($imagen_nueva,$y,$x,$rgbnew);
						}
					}
				}

				//Creamos la imagen
				ImagePng($imagen_nueva,$nombre_salida);  
			
				ImageDestroy($imagen_nueva);
				ImageDestroy($archivo_imagen);
				fclose($archivo_binario);

				//Eliminamos el fichero auxiliar utilizado
				unlink($nombre_binario);

				echo "\n  Fichero ocultado correctamente! :)\n\n";
			}
		}
	}
?>