Académique Documents
Professionnel Documents
Culture Documents
#
#
#
TCS230/TCS3200/ColorPAL Color Match Software
#
#
(C) Copyright 2006, 2009 Bueno Systems, Inc.
#
#
Contact: propeller@phipi.com
#
#
#
# This program is free software; you can redistribute it and/or modify
#
# it under the terms of the GNU General Public License as published by
#
# the Free Software Foundation; either version 2 of the License, or
#
# (at your option) any later version.
#
#
#
# This program is distributed in the hope that it will be useful,
#
# but WITHOUT ANY WARRANTY; without even the implied warranty of
#
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#
# GNU General Public License for more details.
#
#
#
# You should have received a copy of the GNU General Public License
#
# along with this program; if not, write to the Free Software
#
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
#
#
#############################################################################
use
use
use
use
use
use
use
use
use
use
use
Win32::SerialPort qw(:STAT);
Win32::Registry;
Tk;
Tk::Canvas;
Tk::Photo;
Tk::Scale;
Tk::Table;
Tk::DialogBox;
Tk::ROText;
Tk::ToggleButton;
File::Basename;
require
require
require
require
require
require
require
require
require
$CMD_OFF
$CMD_RAW
$CMD_BAL
$CMD_PUT
$CMD_GET
Win32::API;
"utf8_heavy.pl";
"unicore/lib/SpacePer.pl";
"unicore/To/Lower.pl";
"unicore/To/Upper.pl";
"unicore/To/Fold.pl";
"unicore/lib/Digit.pl";
"unicore/lib/Word.pl";
"Encode/Unicode.pm";
=
=
=
=
=
chr(0x40);
chr(0x41);
chr(0x42);
chr(0x43);
chr(0x44);
$DLE = chr(0x10);
my $Registry;
$::HKEY_LOCAL_MACHINE->Open("HARDWARE\\DEVICEMAP\\SERIALCOMM", $Registry) or die
"Can't open data: $^E";
my @PortNames = ();
@RGB = ('#ff0000', '#00ff00', '#0000ff');
@CurrentBlack = (0, 0, 0);
}
Win32::Sleep 1000;
my (undef, $n, undef, $err) = ($Port->status);
if ($err) {
$Port->reset_error;
}
if ($n) {
my $stream = $Port->input;
last if $stream =~ m/R\d+ G\d+ B\d+\r/
}
$Port->close
}
return
}
sub Update {
my $nxt;
$Port->error_msg(1);
my (undef, $n, undef, $err) = ($Port->status);
if ($err) {
$Port->reset_error;
}
if ($n) {
$QuiteTimes = 0;
$stream .= $Port->input;
while ($stream =~ m/(R\d+ G\d+ B\d+)\r/osg) {
$lastRGB = $1;
$nxt = pos($stream);
}
$stream = substr($stream, $nxt) if defined $nxt;
if ($lastRGB && defined $WBMode) {
@color = ($lastRGB =~ m/R(\d+) G(\d+) B(\d+)/);
@CurrentRaw = @color;
if ($WBMode eq $CMD_BAL && defined @CurrentWhite && defi
ned @CurrentBlack) {
@CurrentRGB = map {int(($CurrentRaw[$_] - $Curre
ntBlack[$_]) * 255 / ($CurrentWhite[$_] - $CurrentBlack[$_]))} (0 .. 2)
} else {
@CurrentRGB = @CurrentRaw
}
my $status = grep {$_ > 255} @CurrentRGB;
$Message = $status ? 'Saturated' : '';
foreach my $i (0..2) {
$canBars->itemconfigure($txtBar[$i], -text => $C
urrentRGB[$i]);
$canBars->coords($canBar[$i], 0, $i * 18 + 4, $C
urrentRGB[$i] / 2, $i * 18 + 21)
}
@CurrentRGB = map {$_ > 255 ? 255 : $_} @CurrentRGB;
$fraSwatch->configure(-background => ScreenColor(@Curren
tRGB));
&BestMatch
}
} else {
PutMsg($WBMode) if $QuiteTimes++ > 30
}
}
sub PutMsg {
PutCmd(shift);
} else {
my $no = shift;
my @rgb = @_;
$lblColor[$no]->configure(
-relief => 'sunken',
-background => ScreenColor(@rgb),
);
$DefinedColor[$no] = [$no, @rgb];
&BestMatch
}
}
sub UndefineColor {
my $no = shift;
$lblColor[$no]->configure(-relief => 'raised', -background => GRAY);
$canDist->coords($txtDist[$no], 500,0);
undef $DefinedColor[$no];
&BestMatch;
}
sub FlashSelected {
if (defined $PrevSelected) {
$lblColor[$PrevSelected]->configure(-foreground => BLACK);
}
if (defined $Selected) {
$lblColor[$Selected]->configure(-foreground => $Flash ? BLACK :
YELLOW);
$Flash = not $Flash;
}
$PrevSelected = $Selected
}
sub BestMatch {
my $nBest;
my $distBest = 1e38;
my @Defined = grep defined, @DefinedColor;
foreach (@Defined) {
my ($n, @rgb) = @$_;
my $distMax = 0;
foreach my $i (0..2) {
$dist = abs($rgb[$i] - $CurrentRGB[$i]);
$distMax = $dist if $dist > $distMax
}
$canDist->coords($txtDist[$n], $distMax * 2 + 10, $n * 2 + 10);
if ($distMax < $distBest) {$nBest = $n; $distBest = $distMax}
}
return $Selected = $nBest
}
sub PressWB {
my ($on, $i) = @_;
if ($on) {
if ($i && !defined @CurrentWhite) {
$mw->messageBox(-message => '"White" is undefined. Set w
hite first.', -type => 'ok');
$btnWB[0]->TurnOn;
return
} elsif ($i && !defined @CurrentBlack) {
$mw->messageBox(-message => '"Black" is undefined. Set b
lack first.', -type => 'ok');
$btnWB[0]->TurnOn;
return
}
$WBMode = $i ? $CMD_BAL : $CMD_RAW
}
}
sub DoWhiteBalance {
@CurrentWhite = @CurrentRaw;
$btnWB[1]->TurnOn if defined @CurrentBlack
}
sub DoBlackBalance {
@CurrentBlack = @CurrentRaw;
$btnWB[1]->TurnOn if defined @CurrentWhite
}
sub StoreColors {
PutMsg($CMD_OFF);
$mw->afterCancel($UpdateID);
$Message = '';
$txtMsg->update;
foreach my $no (0..99) {
if (defined $DefinedColor[$no]) {
PutMsg($CMD_PUT, 0x80 + $no, @{$DefinedColor[$no]}[1..3]
);
} else {
PutMsg($CMD_PUT, $no, 0, 0, 0)
}
my $c;
do {
$c = $Port->input
} until $c =~ m/\x43/;
if ($no & 1) {
$Message .= '|';
$txtMsg->update
}
}
PutMsg($WBMode);
$UpdateID = $mw->repeat(50, \&Update);
#
$Message = ''
}
sub RetrieveColors {
PutMsg($CMD_OFF);
$mw->afterCancel($UpdateID);
$Message = '';
$txtMsg->update;
foreach my $no (0..99) {
PutMsg($CMD_GET, $no);
my $c = '';
do {
$c .= $Port->input
} until $c =~ m/\x10\x44(((\x10\x10)|[^\x10]){4})/;
$c = $1;
$c =~ s/\x10\x10/\x10/;
my ($def, @rgb) = map ord, split(//, $c);
if ($def & 0x80) {
DefineColor($no, @rgb);
} else {
UndefineColor($no)
}
if ($no & 1) {
$Message .= '|';
$txtMsg->update
}
}
PutMsg($WBMode);
$UpdateID = $mw->repeat(50, \&Update);
}