Convert array outputted from DCT to an image in PHP - php

Using the following code I can get the DCT of an image in PHP. Then I need to convert this back in to the compressed image. How can I achieve that?
<?php
$results = array();
$image1 = "baboon.jpg";
$ima = ImageCreateFromJPEG($image1);
$N1 = imagesx($ima);
$N2 = imagesy($ima);
$rows = array();
$row = array();
for ($j = 0; $j < $N2; $j++) {
for ($i = 0; $i < $N1; $i++)
$row[$i] = imagecolorat($ima, $i, $j);
$rows[$j] = dct1D($row);
}
for ($i = 0; $i < $N1; $i++) {
for ($j = 0; $j < $N2; $j++)
$col[$j] = $rows[$j][$i];
$results[$i] = dct1D($col);
}
print_r($results);
function dct1D($in) {
$results = array();
$N = count($in);
for ($k = 0; $k < $N; $k++) {
$sum = 0;
for ($n = 0; $n < $N; $n++) {
$sum += $in[$n] * cos($k * pi() * ($n + 0.5) / ($N));
}
$sum *= sqrt(2 / $N);
if ($k == 0) {
$sum *= 1 / sqrt(2);
}
$results[$k] = $sum;
}
return $results;
}
?>
Also I need to know how can I add some extra details like another message to this image too.. (image steganography). Please help. Thanks

Related

Optimisation 3 array and foreach

Hi how can i optimize my code ?
$time_start = microtime(true);
$max = 2000;
$vx = [];
for ($i = 0; $i < $max; $i++) {
$vx[$i] = $i;
}
$vy = [];
for ($i = 0; $i < $max; $i++) {
$vy[$i] = $i;
}
$z = [];
$nb = 0;
foreach ($vx as $kx=>$x) {
foreach ($vy as $ky=>$y) {
$z[$x][$y] = cos($x*$x)-sin($y*-2);
$nb++;
}
}
$time_end = microtime(true);
echo ($time_end-$time_start).' microsec to process and calculate '.$nb.' z values';
And after this
$time_start = microtime(true);
$max = 2000;
$vx = [];
$vy = [];
for ($i = 0; $i < $max; $i++) {
$vx[$i] = $i;
$vy[$i] = $i;
}
$z = [];
$nb = 0;
foreach ($vx as $kx=>$x) {
foreach ($vy as $ky=>$y) {
$z[$x][$y] = cos($x*$x)-sin($y*-2);
$nb++;
}
}
$time_end = microtime(true);
echo ($time_end-$time_start).' microsec to process and calculate '.$nb.' z values';
The foreach loops are not necessary nor are the 2 arrays you build. It can all be done in 2 for loops like this
$max = 10;
$z = [];
for ($i = 0; $i < $max; $i++) {
for ($j = 0; $j < $max; $j++) {
$z[$i][$j] = cos($i*$i)-sin($j*-2);
}
}
print_r($z);
And after this
$time_start = microtime(true);
$max = 2000;
$vx = [];
$vy = [];
for ($i = 0; $i < $max; $i++) {
$vx[$i] = $i;
$vy[$i] = $i;
}
$z = [];
$nb = 0;
for ($i = 0; $i < $max; $i++) {
for ($j = 0; $j < $max; $j++) {
$z[$i][$j] = cos($i*$i)-sin($j*-2);
}
}
$time_end = microtime(true);
echo ($time_end-$time_start).' microsec to process and calculate '.$nb.' z values';```
can i optimise the double foreach ?

How can received and clear an array in PHP

I'm trying to look for a number with maximum divisors in a range of 1 - 10000.
I succeeded, but then I wish to verify if there exist more than two max divisors and print them out. My array is really the problem. How can I clear an array and assign a new integer to it in an if else if statement?
Here is what I have tried:
function countDivisors(){
$input = 10000;
$maxNumOfDiv = -1;
$intWMaxDivs = -1;
$curNumOfDiv = 0;
$arr = array();
for($i=1; $i <= $input; $i++) {
$curNumOfDiv = 0;
for ($j = 1; $j < $i; $j++){
if ($i % $j == 0)
$curNumOfDiv++;
}
if($curNumOfDiv = $maxNumOfDiv){
$arr[] = $i;
$intWMaxDivs = $i;
$maxNumOfDiv = $curNumOfDiv;
} else if($curNumOfDiv > $maxNumOfDiv){
$arr = array();
$arr[] = $intWMaxDivs
$maxNumOfDiv = $curNumOfDiv;
}
}
for ($i; $i < count($arr); $i++){
echo $arr[$i]['intWMaxDivs'];
echo $arr[$i]['maxNumOfDiv'];
}
$div = [];
$maxDivKey = false;
$maxDiv = 0;
for($i = 1; $i <= 10000; $i++) {
for ($j = 1; $j < $i; $j++){
if ($i % $j == 0){
$div[$i][] = $i.'/'.$j.'='.$i/$j;
}
if($j == $i-1){
$count = count($div[$i]);
$div[$i]['count'] = $count;
if($maxDiv < $count){
$maxDiv = $count;
$maxDivKey = $i;
}
}
}
}
echo '<h1>Max divisors:</h1>';
print_r($div[$maxDivKey]);
//print_r($div);
I may be misunderstanding this question a little. If you are looking for a single number with maximum number of dividers, it should be something like this.
<?php
$max_num=10000;
$start_num=1;
$max_divs=-1;
$max_number=-1;
$numbers=array();
$max_divs_arr=array();
for($i=$start_num;$i<=$max_num;$i++)
{
$divs=0;
$div_array=array();
for($j=$start_num;$j<=$i;$j++)
{
if($i%$j==0)
{
$divs++;
$div_array[]=$j;
}
}
if($divs==$max_divs)
$max_divs_arr[$i]=$div_array;
if($divs>$max_divs)
{
$max_divs_arr=array();
$max_divs=$divs;
$max_divs_arr[$i]=$div_array;
}
}
foreach($max_divs_arr as $number=>$divisors)
echo "\nNumber with most divisors is $number\nIt has $max_divs divisors\nThose divisors are:".implode(',',$divisors);

for loop gets executed just once

I have created an array dynamically like this way
$names = array();
for ($i = 0; $i < 100; $i++) {
$names[] = $i;
}
then created part
$parts = count($names) / 20;
and created a sub array then loop through the parts
$j = 0;
for ($i = 0; $i < $parts; $i++) {
echo "Part" . $i."<br>";
$newarray = array_slice($names, $j, 20);
for ($i = 0; $i < count($newarray); $i++) {
echo $i;
}
$j = $j + 20;
}
The problem is that this code displays from zero to 19 It doesn't display the other parts
Both the inner and outer loops use the same control variable $i, so just change the inner one...
$j = 0;
for ($i = 0; $i < $parts; $i++) {
echo "Part" . $i."<br>";
$newarray = array_slice($names, $j, 20);
for ($i1 = 0; $i1 < count($newarray); $i1++) {
echo $i1;
}
$j = $j + 20;
}

Gaussian Eliminate for GF2 code

I have this gauss_eliminate function, but instead of dealing with real numbers, I want it to work on binary values.
I need the GF2 gauss_eliminate function, where the input is binary and the output is binary.
This produces real values, not binary, eg
0.57142857142857
0.71428571428571
-0.42857142857143
-0.28571428571429
0.14285714285714
Gaussian elimination has these 3 allowed steps:
1) Swapping two rows (for achieving a certain look)
2) Multiplying a row by a nonzero number,
3) Adding a multiple of one row to another row.
-- in GF2: addition operation is XOR : 0+0=0, 0+1=1, 1+0=1, 1+1=0 --and--
multiplication is AND operation: 0*0=0,0*1=0,1*0=0,1*1=1
function gauss_eliminate($A, $b, $N)
{
for ($col = 0; $col < $N; $col++) {
$j = $col;
$max = $A[$j][$j];
for ($i = $col + 1; $i < $N; $i++) {
$tmp = abs($A[$i][$col]);
if ($tmp > $max) {
$j = $i;
$max = $tmp;
}
}
swap_rows($A, $b, $col, $j);
for ($i = $col + 1; $i < $N; $i++) {
$tmp = $A[$i][$col] / $A[$col][$col];
for ($j = $col + 1; $j < $N; $j++) $A[$i][$j] -= $tmp * $A[$col][$j];
$A[$i][$col] = 0;
$b[$i] -= $tmp * $b[$col];
}
}
$x = array();
for ($col = $N - 1; $col >= 0; $col--) {
$tmp = $b[$col];
for ($j = $N - 1; $j > $col; $j--) $tmp -= $x[$j] * $A[$col][$j];
$x[$col] = $tmp / $A[$col][$col];
}
return $x;
}
new code #1, still doesn't work:
function gauss_eliminate($A, $b, $N)
{
for ($col = 0; $col < $N; $col++) {
$j = $col;
$max = $A[$j][$j];
for ($i = $col + 1; $i < $N; $i++) {
$tmp = abs($A[$i][$col]);
if ($tmp > $max) {
$j = $i;
$max = $tmp;
}
}
swap_rows($A, $b, $col, $j);
for ($i = $col + 1; $i < $N; $i++) {
for ($j = $col + 1; $j < $N; $j++)
$A[$i][$j]=( $A[$i][$j] != $A[$col][$j] ) ? 1 : 0;
$A[$i][$col] = 0;
$b[$i]=( $b[$i] != $b[$col] ) ? 1 : 0;
}
}
$x = array();
for ($col = $N - 1; $col >= 0; $col--) {
# $tmp = $b[$col];
# for ($j = $N - 1; $j > $col; $j--) $tmp -= $x[$j] * $A[$col][$j];
$x[$col] = ( $x[$col] != $A[$col][$j] ) ? 1 : 0;
}
return $x;
}
New code #2 - still doesn't work - tmp setup to alternate
function gauss_eliminate($A, $b, $N)
{
for ($col = 0; $col < $N; $col++) {
$j = $col;
$max = $A[$j][$j];
for ($i = $col + 1; $i < $N; $i++) {
$tmp = abs($A[$i][$col]);
if ($tmp > $max) { $j = $i; $max = $tmp; }
}
swap_rows($A, $b, $col, $j);
for ($i = $col + 1; $i < $N; $i++) {
# $tmp = $A[$i][$col] / $A[$col][$col];
for ($j = $col + 1; $j < $N; $j++) $A[$i][$j]=($A[$i][$j] != $A[$col][$j] ? 1 : 0);
$A[$i][$col] = 0;
$b[$i] = ( $b[$i] != $b[$col] ? 1 : 0);
}
}
$x = array();
for ($col = $N - 1; $col >= 0; $col--) {
$tmp = $b[$col];
for ($j = $N - 1; $j > $col; $j--) $tmp = 1 - $tmp;
$x[$col] = ($tmp != $A[$col][$j] ? 1 : 0);
}
return $x;
}
It appears I found the right syntax. I am getting the right result for one example, after modifying the code in a way that makes sense.... converting - to +, and this + to XOR, while / is ignored and * is AND.
Still it would be nice to get a confirmation that this code is correct.
function gauss_eliminate($A, $b, $N) {
for ($col = 0; $col < $N; $col++) {
$j = $col;
$max = $A[$j][$j];
for ($i = $col + 1; $i < $N; $i++) {
$tmp = abs($A[$i][$col]);
if ($tmp > $max) {
$j = $i;
$max = $tmp;
}
}
swap_rows($A, $b, $col, $j);
for ($i = $col + 1; $i < $N; $i++) {
# $tmp = $A[$i][$col] / $A[$col][$col];
# for ($j = $col + 1; $j < $N; $j++) {
# $A[$i][$j] -= $tmp * $A[$col][$j];
# }
# $A[$i][$col] = 0;
# $b[$i] -= $tmp * $b[$col];
$tmp = $A[$i][$col];
for ($j = $col + 1; $j < $N; $j++) {
# $A[$i][$j] = $A[$i][$j] + ( $tmp * $A[$col][$j] );
$A[$i][$j] = ( $A[$i][$j] != ( $tmp && $A[$col][$j] ) ) ? 1 : 0;
}
$A[$i][$col] = 0;
# $b[$i] = $b[$i] + ($tmp * $b[$col]);
$b[$i] = ( $b[$i] != ($tmp && $b[$col]) ) ? 1 : 0;
}
}
$x = array();
for ($col = $N - 1; $col >= 0; $col--) {
$tmp = $b[$col];
for ($j = $N - 1; $j > $col; $j--) {
# $tmp -= $x[$j] * $A[$col][$j];
# $tmp = $tmp + ($x[$j] * $A[$col][$j]);
$tmp = ( $tmp != ($x[$j] && $A[$col][$j]) ) ? 1 : 0;
}
# $x[$col] = $tmp / $A[$col][$col];
$x[$col] = $tmp;
}
return $x;
}
The commented text is the old (non GF2 code) as well as my "middle step" of showing where I convert + to XOR, * to AND, etc

Undefined offset: 255

Logfiles are full of this error:
Undefined offset: 255 in /var/www/html/site2/functions.inc.php on line 764"
The line 764 is the following:
$counter[$i] = $counter[$x];
The whole function see below.
Can somebody help me to fix it? Thanks.
function Encode($data,$pwd) {
$pwd_length = strlen($pwd);
for ($i = 0; $i < 255; $i++) {
$key[$i] = ord(substr($pwd, ($i % $pwd_length)+1, 1));
$counter[$i] = $i;
}
$x = '';
for ($i = 0; $i < 255; $i++) {
$x = ($x + $counter[$i] + $key[$i]) % 256;
$temp_swap = $counter[$i];
$counter[$i] = $counter[$x];
$counter[$x] = $temp_swap;
}
$a = '';
$j = '';
$Zcrypt = '';
for ($i = 0; $i < strlen($data); $i++) {
$a = ($a + 1) % 256;
$j = ($j + $counter[$a]) % 256;
$temp = $counter[$a];
$counter[$a] = $counter[$j];
$counter[$j] = $temp;
$k = $counter[(($counter[$a] + $counter[$j]) % 256)];
$Zcipher = ord(substr($data, $i, 1)) ^ $k;
$Zcrypt .= chr($Zcipher);
}
return $Zcrypt;
}
Your for-loop stops when $i >= 255. You don't want that. I think you want the for-loop to stop at $i>255.
So change
for ($i = 0; $i < 255; $i++) {
into
for ($i = 0; $i <= 255; $i++) {
And you're good to go!

Categories