File Coverage

lib/SIRTX/VM/Chunk/Type/ColourPalette.pm
Criterion Covered Total %
statement 17 74 22.9
branch 0 26 0.0
condition 0 9 0.0
subroutine 6 13 46.1
pod 4 4 100.0
total 27 126 21.4


line stmt bran cond sub pod time code
1             # Copyright (c) 2025 Philipp Schafft
2              
3             # licensed under Artistic License 2.0 (see LICENSE file)
4              
5             # ABSTRACT: module for interacting with SIRTX VM chunks
6              
7              
8             package SIRTX::VM::Chunk::Type::ColourPalette;
9              
10 1     1   4434 use v5.16;
  1         4  
11 1     1   5 use strict;
  1         2  
  1         44  
12 1     1   6 use warnings;
  1         3  
  1         96  
13              
14 1     1   8 use Carp;
  1         2  
  1         99  
15              
16 1     1   890 use Data::URIID::Colour;
  1         3335  
  1         45  
17              
18 1     1   8 use parent 'SIRTX::VM::Chunk::Type';
  1         2  
  1         7  
19              
20             our $VERSION = v0.03;
21              
22              
23             sub offset {
24 0     0 1   my ($self, $n, @opts) = @_;
25              
26 0 0         croak 'Stray options passed' if scalar @opts;
27              
28 0 0         if (defined $n) {
29 0           $n = int($n);
30              
31 0 0 0       if ($n < 1 || $n > 0xFFFF) {
32 0           croak 'Invalid offset';
33             }
34              
35 0           $self->{type_data}{offset} = $n;
36             }
37              
38 0           return $self->{type_data}{offset};
39             }
40              
41              
42             sub get_colour {
43 0     0 1   my ($self, $idx, @opts) = @_;
44              
45 0 0         croak 'Stray options passed' if scalar @opts;
46              
47 0           $idx = int($idx) - $self->{type_data}{offset};
48              
49 0 0         croak 'Invalid index, did you try a relative offset as index' if $idx < 0;
50              
51 0   0       return $self->{type_data}{colours}[$idx] // croak 'No such entry';
52             }
53              
54              
55             sub set_colour {
56 0     0 1   my ($self, $idx, $colour, @opts) = @_;
57 0           my $type_data = $self->{type_data};
58              
59 0 0         croak 'Stray options passed' if scalar @opts;
60              
61 0           $idx = int($idx) - $type_data->{offset};
62              
63 0 0         croak 'Invalid index, did you try a relative offset as index' if $idx < 0;
64              
65 0 0         unless (eval {$colour->isa('Data::URIID::Colour')}) {
  0            
66 0           $colour = Data::URIID::Colour->new(rgb => $colour);
67             }
68              
69 0 0         if ($idx > 0) {
70 0 0         croak 'Setting colour would create hole' unless defined $type_data->{colours}[$idx - 1];
71             }
72              
73 0           $type_data->{colours}[$idx] = $colour;
74              
75 0           return $self;
76             }
77              
78              
79             sub add_colour {
80 0     0 1   my ($self, $colour, @opts) = @_;
81              
82 0 0         croak 'Stray options passed' if scalar @opts;
83              
84 0 0         unless (eval {$colour->isa('Data::URIID::Colour')}) {
  0            
85 0           $colour = Data::URIID::Colour->new(rgb => $colour);
86             }
87              
88 0           push(@{$self->{type_data}{colours}}, $colour);
  0            
89             }
90              
91             # ---- Private helpers ----
92              
93             sub _create_data {
94 0     0     my ($self) = @_;
95 0           my $str = "\0\0";
96 0           open(my $fh, '<:raw', \$str);
97 0           $self->SIRTX::VM::Chunk::attach_data($fh);
98             }
99              
100             sub _parse {
101 0     0     my ($self) = @_;
102 0           my $length = $self->_data_length;
103 0           my @colours;
104 0           my $type_data = $self->{type_data} = {colours => \@colours};
105 0           my $offset = 2;
106 0           my $data;
107              
108 0 0 0       if ($length < 2 || (($length - 2) % 3) != 0) {
109 0           croak 'Invalid data, bad length';
110             }
111              
112 0           $type_data->{offset} = unpack('n', $self->read_data(2));
113              
114 0           while ($offset < $length) {
115 0           my ($r, $g, $b) = unpack('CCC', $self->read_data(3, $offset));
116              
117 0           push(@colours, Data::URIID::Colour->new(rgb => sprintf('#%02x%02x%02x', $r, $g, $b)));
118              
119 0           $offset += 3;
120             }
121             }
122              
123             sub _render {
124 0     0     my ($self) = @_;
125 0           my $type_data = $self->{type_data};
126 0           my $str = join('', map {substr($_->rgb, 1)} @{$type_data->{colours}});
  0            
  0            
127              
128 0           $str = pack('nH*', $type_data->{offset}, $str);
129              
130 0           open(my $fh, '<:raw', \$str);
131 0           $self->SIRTX::VM::Chunk::attach_data($fh);
132             }
133              
134             1;
135              
136             __END__
137              
138             =pod
139              
140             =encoding UTF-8
141              
142             =head1 NAME
143              
144             SIRTX::VM::Chunk::Type::ColourPalette - module for interacting with SIRTX VM chunks
145              
146             =head1 VERSION
147              
148             version v0.03
149              
150             =head1 SYNOPSIS
151              
152             use SIRTX::VM::Chunk::Type::ColourPalette;
153              
154             my SIRTX::VM::Chunk $chunk = SIRTX::VM::Chunk::Type::ColourPalette->new;
155              
156             $chunk->offset($first_id);
157             $chunk->add_colour(@colours);
158              
159             (since v0.02)
160              
161             This type represents a colour palette.
162             Such a palette consists of a number of colour values being mapped to C<user-defined-identifier>s.
163              
164             This inherits from L<SIRTX::VM::Chunk>.
165              
166             =head2 offset
167              
168             my $offset = $chunk->offset;
169             # or:
170             $chunk->offset($offset);
171              
172             (experimental since v0.02)
173              
174             This gets or sets the offset of the colour plaette into the C<user-defined-identifier> space.
175              
176             The types and ranges used by this method are subject to change.
177              
178             B<Note:>
179             As per specification of the identifier space a value of zero (null-identifier) is invalid.
180             Values past C<2^16-1> (or: C<0xFFFF>) are also invalid.
181              
182             =head2 get_colour
183              
184             my $colour = $chunks->get_colour($idx);
185              
186             (experimental since v0.02)
187              
188             Gets a colour by it's C<user-defined-identifier>.
189              
190             The types and ranges used by this method are subject to change.
191              
192             =head2 set_colour
193              
194             $chunks->set_colour($idx => $colour);
195              
196             (experimental since v0.02)
197              
198             Sets a colour by it's C<user-defined-identifier>.
199              
200             The types and ranges used by this method are subject to change.
201              
202             B<Note:>
203             This method may refuse setting colours if the result would creat an invalid state that could not be written.
204             This is specifically true for creating holes.
205             Hence it is recommended to add colours using L</add_colour> or add them in-order.
206              
207             =head2 add_colour
208              
209             $chunks->add_colour($colour);
210              
211             (experimental since v0.02)
212              
213             Adds a colour to the palette.
214              
215             The types and ranges used by this method are subject to change.
216              
217             =head1 AUTHOR
218              
219             Philipp Schafft <lion@cpan.org>
220              
221             =head1 COPYRIGHT AND LICENSE
222              
223             This software is Copyright (c) 2025 by Philipp Schafft <lion@cpan.org>.
224              
225             This is free software, licensed under:
226              
227             The Artistic License 2.0 (GPL Compatible)
228              
229             =cut