6
namespace FSpot.Imaging.Ciff {
11
public enum EntryType : ushort {
25
/* See http://www.sno.phy.queensu.ca/~phil/exiftool/canon_raw.html */
26
internal struct Entry {
31
public Entry (byte [] data, int pos, bool little)
33
Tag = (Tag) BitConverter.ToUInt16 (data, pos, little);
34
Size = BitConverter.ToUInt32 (data, pos + 2, little);
35
Offset = BitConverter.ToUInt32 (data, pos + 6, little);
39
class ImageDirectory {
40
System.Collections.ArrayList entry_list;
45
System.IO.Stream stream;
47
public ImageDirectory (System.IO.Stream stream, uint start, long end, bool little)
53
entry_list = new System.Collections.ArrayList ();
55
stream.Position = end - 4;
56
byte [] buf = new byte [10];
57
stream.Read (buf, 0, 4);
58
uint directory_pos = BitConverter.ToUInt32 (buf, 0, little);
59
DirPosition = start + directory_pos;
61
stream.Position = DirPosition;
62
stream.Read (buf, 0, 2);
64
Count = BitConverter.ToUInt16 (buf, 0, little);
66
for (int i = 0; i < Count; i++)
68
stream.Read (buf, 0, 10);
69
Log.DebugFormat ("reading {0} {1}", i, stream.Position);
70
Entry entry = new Entry (buf, 0, little);
71
entry_list.Add (entry);
75
public ImageDirectory ReadDirectory (Tag tag)
77
foreach (Entry e in entry_list) {
79
uint subdir_start = this.start + e.Offset;
80
ImageDirectory subdir = new ImageDirectory (stream, subdir_start, subdir_start + e.Size, little);
87
public byte [] ReadEntry (int pos)
89
Entry e = (Entry) entry_list [pos];
91
stream.Position = this.start + e.Offset;
93
byte [] data = new byte [e.Size];
94
stream.Read (data, 0, data.Length);
99
public byte [] ReadEntry (Tag tag)
102
foreach (Entry e in entry_list) {
104
return ReadEntry (pos);
111
public class CiffFile : BaseImageFile {
114
System.IO.Stream stream;
116
ImageDirectory Root {
119
stream = PixbufStream ();
120
root = Load (stream);
127
public CiffFile (SafeUri uri) : base (uri)
131
private ImageDirectory Load (System.IO.Stream stream)
133
byte [] header = new byte [26]; // the spec reserves the first 26 bytes as the header block
134
stream.Read (header, 0, header.Length);
138
little = (header [0] == 'I' && header [1] == 'I');
140
start = BitConverter.ToUInt32 (header, 2, little);
142
// HEAP is the type CCDR is the subtype
143
if (System.Text.Encoding.ASCII.GetString (header, 6, 8) != "HEAPCCDR")
144
throw new ImageFormatException ("Invalid Ciff Header Block");
146
long end = stream.Length;
147
return new ImageDirectory (stream, start, end, little);
150
public override System.IO.Stream PixbufStream ()
152
byte [] data = GetEmbeddedJpeg ();
155
return new System.IO.MemoryStream (data);
157
return DCRawFile.RawPixbufStream (Uri);
160
private byte [] GetEmbeddedJpeg ()
162
return Root.ReadEntry (Tag.JpgFromRaw);
165
protected override void Close ()
167
if (stream != null) {