1 /* $Id: image_io_raw.cpp 128295 2008-05-21 14:18:11Z lavr $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Authors: Mike DiCuccio
27 *
28 * File Description:
29 * CImageIORaw -- interface class for reading/writing Windows RAW files
30 */
31
32 #include <ncbi_pch.hpp>
33 #include "image_io_raw.hpp"
34 #include <util/image/image.hpp>
35 #include <util/image/image_exception.hpp>
36
37 BEGIN_NCBI_SCOPE
38
39
40 // header signature
41 static const char* sc_Header = "RAW\0";
42
43
ReadImage(CNcbiIstream & istr)44 CImage* CImageIORaw::ReadImage(CNcbiIstream& istr)
45 {
46 // read header
47 char header[4];
48 istr.read(reinterpret_cast<char*>(&header), 4);
49
50 // read dimensions
51 size_t width;
52 size_t height;
53 size_t depth;
54
55 istr.read(reinterpret_cast<char*>(&width), sizeof(size_t));
56 istr.read(reinterpret_cast<char*>(&height), sizeof(size_t));
57 istr.read(reinterpret_cast<char*>(&depth), sizeof(size_t));
58
59 CRef<CImage> image(new CImage(width, height, depth));
60 if ( !image ) {
61 NCBI_THROW(CImageException, eReadError,
62 "CImageIORaw::ReadImage(): failed to allocate image");
63 }
64
65 istr.read(reinterpret_cast<char*>(image->SetData()),
66 width * height * depth);
67 return image.Release();
68 }
69
70
ReadImage(CNcbiIstream & istr,size_t x,size_t y,size_t w,size_t h)71 CImage* CImageIORaw::ReadImage(CNcbiIstream& istr,
72 size_t x, size_t y, size_t w, size_t h)
73 {
74 // read header
75 char header[4];
76 istr.read(reinterpret_cast<char*>(&header), 4);
77
78 // read dimensions
79 size_t width;
80 size_t height;
81 size_t depth;
82
83 istr.read(reinterpret_cast<char*>(&width), sizeof(size_t));
84 istr.read(reinterpret_cast<char*>(&height), sizeof(size_t));
85 istr.read(reinterpret_cast<char*>(&depth), sizeof(size_t));
86
87 // create our sub-image
88 CRef<CImage> image(new CImage(w, h, depth));
89 if ( !image ) {
90 NCBI_THROW(CImageException, eReadError,
91 "CImageIORaw::ReadImage(): failed to allocate image");
92 }
93
94 // calculate the bytes per line for our sub-image anf dor the input image
95 const size_t input_bpl = width * depth;
96 const size_t output_bpl = w * depth;
97
98 // start reading
99 unsigned char* data = image->SetData();
100 istr.seekg(input_bpl * y + x * depth, ios::beg);
101 for (size_t i = 0; i < h; ++i, data += output_bpl) {
102 istr.read(reinterpret_cast<char*>(data), output_bpl);
103 istr.seekg(input_bpl - output_bpl, ios::cur);
104 }
105 return image.Release();
106 }
107
108
ReadImageInfo(CNcbiIstream &,size_t *,size_t *,size_t *)109 bool CImageIORaw::ReadImageInfo(CNcbiIstream&,
110 size_t*, size_t*, size_t*)
111 {
112 NCBI_THROW(CImageException, eUnsupported,
113 "CImageIORaw::ReadImageInfo(): RAW format inspection "
114 "unimplemented");
115 }
116
117
WriteImage(const CImage & image,CNcbiOstream & ostr,CImageIO::ECompress)118 void CImageIORaw::WriteImage(const CImage& image, CNcbiOstream& ostr,
119 CImageIO::ECompress)
120 {
121 // write the header
122 ostr.write(reinterpret_cast<const char*>(sc_Header), 4);
123
124 // write dimensions
125 size_t width = image.GetWidth();
126 size_t height = image.GetHeight();
127 size_t depth = image.GetDepth();
128
129 ostr.write(reinterpret_cast<const char*>(&width), sizeof(size_t));
130 ostr.write(reinterpret_cast<const char*>(&height), sizeof(size_t));
131 ostr.write(reinterpret_cast<const char*>(&depth), sizeof(size_t));
132
133 // write the image data
134 ostr.write(reinterpret_cast<const char*>(image.GetData()),
135 width * height * depth);
136 }
137
138
WriteImage(const CImage & image,CNcbiOstream & ostr,size_t,size_t y,size_t width,size_t height,CImageIO::ECompress)139 void CImageIORaw::WriteImage(const CImage& image, CNcbiOstream& ostr,
140 size_t /* x */, size_t y,
141 size_t width, size_t height,
142 CImageIO::ECompress)
143 {
144 // write the header
145 ostr.write(reinterpret_cast<const char*>(sc_Header), 4);
146
147 // write dimensions
148 size_t depth = image.GetDepth();
149
150 ostr.write(reinterpret_cast<const char*>(&width), sizeof(size_t));
151 ostr.write(reinterpret_cast<const char*>(&height), sizeof(size_t));
152 ostr.write(reinterpret_cast<const char*>(&depth), sizeof(size_t));
153
154 // calculate the bytes per line for our sub-image anf dor the input image
155 const size_t input_bpl = image.GetWidth() * depth;
156 const size_t output_bpl = width * depth;
157
158 // write the image data
159 const unsigned char* data = image.GetData();
160 data += input_bpl * y;
161 for (size_t i = 0; i < height; ++i, data += input_bpl) {
162 ostr.write(reinterpret_cast<const char*>(data), output_bpl);
163 }
164 }
165
166
167 END_NCBI_SCOPE
168