summaryrefslogtreecommitdiff
path: root/src/photos/PhotoFileAdapter.vala
blob: df49edbc0380a0d796cf0c0fa246ceded1253db4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* Copyright 2016 Software Freedom Conservancy Inc.
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later).  See the COPYING file in this distribution.
 */

//
// PhotoFileAdapter
//
// PhotoFileAdapter (and its immediate children, PhotoFileReader and PhotoFileWriter) are drivers
// hiding details of reading and writing image files and their metadata.  They should keep
// minimal state beyond the filename, if any stat at all.  In particular, they should avoid caching
// values, especially the readers, as writers may be created at any time and invalidate that
// information, unless the readers monitor the file for these changes.
//
// PhotoFileAdapters should be entirely thread-safe.  They are not, however, responsible for
// atomicity on the filesystem.
//

public abstract class PhotoFileAdapter {
    private string filepath;
    private PhotoFileFormat file_format;
    private File file = null;
    
    public PhotoFileAdapter(string filepath, PhotoFileFormat file_format) {
        this.filepath = filepath;
        this.file_format = file_format;
    }
    
    public bool file_exists() {
        return FileUtils.test(filepath, FileTest.IS_REGULAR);
    }
    
    public string get_filepath() {
        return filepath;
    }
    
    public File get_file() {
        File result;
        lock (file) {
            if (file == null)
                file = File.new_for_path(filepath);
            
            result = file;
        }
        
        return result;
    }
    
    public PhotoFileFormat get_file_format() {
        return file_format;
    }
}

//
// PhotoFileReader
//

public abstract class PhotoFileReader : PhotoFileAdapter {
    public enum Role {
        DEFAULT,
        THUMBNAIL
    }

    PhotoFileReader.Role role = Role.DEFAULT;

    protected PhotoFileReader(string filepath, PhotoFileFormat file_format) {
        base (filepath, file_format);
    }
    
    public PhotoFileWriter create_writer() throws PhotoFormatError {
        return get_file_format().create_writer(get_filepath());
    }
    
    public PhotoFileMetadataWriter create_metadata_writer() throws PhotoFormatError {
        return get_file_format().create_metadata_writer(get_filepath());
    }
    
    public abstract PhotoMetadata read_metadata() throws Error;
    
    public abstract Gdk.Pixbuf unscaled_read() throws Error;
    
    public virtual Gdk.Pixbuf scaled_read(Dimensions full, Dimensions scaled) throws Error {
        return resize_pixbuf(unscaled_read(), scaled, Gdk.InterpType.BILINEAR);
    }

    public void set_role (PhotoFileReader.Role role) {
        this.role = role;
    }

    public PhotoFileReader.Role get_role () {
        return this.role;
    }
}

//
// PhotoFileWriter
//

public abstract class PhotoFileWriter : PhotoFileAdapter {
    protected PhotoFileWriter(string filepath, PhotoFileFormat file_format) {
        base (filepath, file_format);
    }
    
    public PhotoFileReader create_reader() {
        return get_file_format().create_reader(get_filepath());
    }
    
    public abstract void write(Gdk.Pixbuf pixbuf, Jpeg.Quality quality) throws Error;
}

//
// PhotoFileMetadataWriter
//

public abstract class PhotoFileMetadataWriter : PhotoFileAdapter {
    protected PhotoFileMetadataWriter(string filepath, PhotoFileFormat file_format) {
        base (filepath, file_format);
    }
    
    public PhotoFileReader create_reader() {
        return get_file_format().create_reader(get_filepath());
    }
    
    public abstract void write_metadata(PhotoMetadata metadata) throws Error;
}