~ubuntu-branches/ubuntu/saucy/cuyo/saucy

« back to all changes in this revision

Viewing changes to datasrc/pics/pam.ml

  • Committer: Bazaar Package Importer
  • Author(s): Angel Abad
  • Date: 2010-07-19 09:54:44 UTC
  • mfrom: (4.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20100719095444-ecoegzo1vvvdwra9
Tags: 2.~-1.1.brl3-1ubuntu1
* Merge from debian unstable (LP: #607106). Remaining changes:
  - Don't register MimeType=application/x-executable in
    the .desktop file.
  - Remove UTF-8 in the .desktop file
  - 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
(*
2
 
   Copyright 2005,2006 by Mark Weyer
3
 
 
4
 
   This program is free software; you can redistribute it and/or modify
5
 
   it under the terms of the GNU General Public License as published by
6
 
   the Free Software Foundation; either version 2 of the License, or
7
 
   (at your option) any later version.
8
 
 
9
 
   This program is distributed in the hope that it will be useful,
10
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
   GNU General Public License for more details.
13
 
 
14
 
   You should have received a copy of the GNU General Public License
15
 
   along with this program; if not, write to the Free Software
16
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
*)
18
 
 
19
 
exception Invalid_PAM
20
 
 
21
 
let whitespace = String.contains " \t\n"
22
 
 
23
 
 
24
 
 
25
 
type basic_pamdata =
26
 
  int * int * int * int *               (* width, height, depth, maxval *)
27
 
  int array array array
28
 
 
29
 
type pamdata = basic_pamdata * string   (* tuple type *)
30
 
 
31
 
 
32
 
 
33
 
let rec read_token line p =
34
 
  let rec finish_token q =
35
 
    if q=(String.length line)
36
 
      then q
37
 
      else if whitespace (String.get line q)
38
 
        then q
39
 
        else finish_token (q+1)  in
40
 
  if p=(String.length line)
41
 
    then None
42
 
    else if whitespace (String.get line p)
43
 
      then read_token line (p+1)
44
 
      else let p'=finish_token p  in
45
 
        Some (String.sub line p (p'-p), p')
46
 
 
47
 
let rec tokenize line p =
48
 
  match read_token line p  with
49
 
    None -> []  |
50
 
    Some (t,p') -> t::(tokenize line p')
51
 
 
52
 
let rec read_tupletype line p q =
53
 
  if p>q
54
 
    then ""
55
 
    else if whitespace (String.get line p)
56
 
      then read_tupletype line (p+1) q
57
 
      else if whitespace (String.get line q)
58
 
        then read_tupletype line p (q-1)
59
 
        else String.sub line p (q-p+1)
60
 
 
61
 
let read_headerline channel =
62
 
  let line = input_line channel  in
63
 
  if (String.length line)=0  then None  else
64
 
  if (String.get line 0)='#'  then None  else
65
 
  match read_token line 0  with
66
 
    None -> None  |
67
 
    Some (t,p) -> if t="TUPLTYPE"
68
 
      then Some (t::[read_tupletype line p ((String.length line)-1)])
69
 
      else Some (t::(tokenize line p))
70
 
 
71
 
let read_pamheader channel =
72
 
  (* The "P7" of the magic number is already read, the "\n" is not *)
73
 
  let magic = input_line channel  in
74
 
  if magic<>""  then raise Invalid_PAM  else
75
 
  let rec parse_header ll =
76
 
    match read_headerline channel  with
77
 
      None -> parse_header ll  |
78
 
      Some ["ENDHDR"] -> ll  |
79
 
      Some l -> parse_header (l::ll)  in
80
 
  let header = parse_header []  in
81
 
  let find_num token =
82
 
    let line = List.find (function [] -> false | h::t -> h=token) header  in
83
 
    match line with
84
 
      h::n::t -> int_of_string n  in
85
 
  let width = find_num "WIDTH"  in
86
 
  let height = find_num "HEIGHT"  in
87
 
  let depth = find_num "DEPTH"  in
88
 
  let maxval = find_num "MAXVAL"  in
89
 
  let tuple_type = List.fold_left
90
 
    (function sofar -> (function
91
 
      [token;value] -> if token="TUPLTYPE"  then value^" "^sofar  else sofar  |
92
 
      l -> sofar))
93
 
    ""  header  in
94
 
  (width,height,depth,maxval,tuple_type)
95
 
 
96
 
 
97
 
 
98
 
let rec read_number channel =
99
 
  let c = input_char channel  in
100
 
  if whitespace c  then read_number channel  else
101
 
  let rec read_rest s =
102
 
    let c = input_char channel  in
103
 
    if whitespace c  then s  else read_rest (s^(String.make 1 c))  in
104
 
  int_of_string (read_rest (String.make 1 c))
105
 
 
106
 
let read_ppmheader channel =
107
 
  let width = read_number channel  in
108
 
  let height = read_number channel  in
109
 
  let maxval = read_number channel  in
110
 
  (width,height,3,maxval,"")
111
 
 
112
 
let rec read_string channel num =
113
 
  if num=0
114
 
    then ""
115
 
    else
116
 
      let c=input_char channel  in
117
 
      (String.make 1 c)^(read_string channel (num-1))
118
 
 
119
 
let numbytes n =
120
 
  let rec loop bytes maxplus1 = if maxplus1>n
121
 
    then bytes
122
 
    else loop (bytes+1) (maxplus1*256)  in
123
 
  loop 0 1
124
 
 
125
 
let read_pam channel =
126
 
  match (match read_string channel 2  with
127
 
    "P7" -> read_pamheader channel  |
128
 
    "P6" -> read_ppmheader channel  |
129
 
    s -> raise Invalid_PAM)
130
 
  with  width,height,depth,maxval,tuple_type  ->
131
 
  let bytes = numbytes maxval  in
132
 
  let rec read_sample sample bytes =
133
 
    if bytes=0
134
 
      then sample
135
 
      else read_sample (sample*256+(input_byte channel)) (bytes-1)  in
136
 
  let read_sample u = read_sample 0 bytes  in
137
 
  ((width,height,depth,maxval,
138
 
    Array.init height (function y ->
139
 
      Array.init width (function x ->
140
 
        Array.init depth read_sample))),
141
 
    tuple_type)
142
 
 
143
 
 
144
 
 
145
 
let write_pam channel ((width,height,depth,maxval,data),tuple_type) =
146
 
  let write_num token num =
147
 
    output_string channel (token^" "^(string_of_int num)^"\n")  in
148
 
  let bytes = numbytes maxval  in
149
 
  let rec write_sample sample bytes =
150
 
    if bytes=0
151
 
      then ()
152
 
      else (write_sample (sample/256) (bytes-1);
153
 
        output_byte channel (sample mod 256))  in
154
 
  let write_sample sample = write_sample sample bytes  in
155
 
  output_string channel "P7\n";
156
 
  write_num "WIDTH" width;
157
 
  write_num "HEIGHT" height;
158
 
  write_num "DEPTH" depth;
159
 
  write_num "MAXVAL" maxval;
160
 
  output_string channel ("TUPLTYPE "^tuple_type^"\n");
161
 
  output_string channel "ENDHDR\n";
162
 
  Array.iter (Array.iter (Array.iter write_sample)) data
163
 
 
164
 
 
165
 
 
166
 
let pam_channel p (width,height,depth,maxval,data) =
167
 
  let rec outdepth sofar n = if n=depth
168
 
    then sofar
169
 
    else outdepth (if p n  then sofar+1  else sofar) (n+1)  in
170
 
  let outdepth = outdepth 0 0  in
171
 
  let rec from_channel inn outn = if p inn
172
 
    then if outn=0  then inn  else from_channel (inn+1) (outn-1)
173
 
    else from_channel (inn+1) outn  in
174
 
  let from_channel = from_channel 0  in
175
 
  (width,height,outdepth,maxval,
176
 
    Array.init height (function y ->
177
 
      Array.init width (function x ->
178
 
        Array.init outdepth (function n ->
179
 
          data.(y).(x).(from_channel n)))))
180
 
 
181
 
 
182
 
 
183
 
let pam_stack (width1,height1,depth1,maxval1,data1)
184
 
    (width2,height2,depth2,maxval2,data2) =
185
 
  (width1,height1,depth1+depth2,maxval1,
186
 
    Array.init height1 (function y ->
187
 
      Array.init width1 (function x ->
188
 
        Array.init (depth1+depth2) (function n ->
189
 
          if n<depth1
190
 
            then data1.(y).(x).(n)
191
 
            else data2.(y).(x).(n-depth1)))))
192
 
 
193