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