libopenraw
|
00001 /* 00002 * libopenraw - rawdata.cpp 00003 * 00004 * Copyright (C) 2007 Hubert Figuiere 00005 * Copyright (C) 2008 Novell, Inc. 00006 * 00007 * This library is free software: you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License 00009 * as published by the Free Software Foundation, either version 3 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library. If not, see 00019 * <http://www.gnu.org/licenses/>. 00020 */ 00021 00022 #include <assert.h> 00023 00024 #include <libopenraw++/rawdata.h> 00025 #include <libopenraw++/rawfile.h> 00026 00027 namespace OpenRaw { 00028 00029 class RawData::Private { 00030 public: 00031 RawData *self; 00032 uint16_t min, max; 00033 CfaPattern cfa_pattern; 00034 uint32_t compression; 00035 uint8_t *pos; 00036 size_t offset; 00037 size_t row_offset; 00038 uint8_t slice; 00039 uint32_t sliceWidth; 00040 uint32_t sliceOffset; 00042 std::vector<uint16_t> slices; 00044 Private(RawData *_self) 00045 : self(_self), 00046 min(0), max(0), 00047 cfa_pattern(OR_CFA_PATTERN_NONE), 00048 compression(0), 00049 pos(NULL), offset(0), 00050 row_offset(0), 00051 slice(0), sliceWidth(0), 00052 sliceOffset(0), slices() 00053 { 00054 } 00055 void advance(size_t s); 00056 void nextSlice(); 00057 void nextRow(); 00058 private: 00059 Private(const Private &); 00060 Private & operator=(const Private &); 00061 }; 00062 00063 00064 RawData * 00065 RawData::getAndExtractRawData(const char* filename, uint32_t options, 00066 or_error & err) 00067 { 00068 err = OR_ERROR_NONE; 00069 RawData *rawdata = NULL; 00070 00071 RawFile *file = RawFile::newRawFile(filename); 00072 if (file) { 00073 rawdata = new RawData(); 00074 err = file->getRawData(*rawdata, options); 00075 delete file; 00076 } 00077 else { 00078 err = OR_ERROR_CANT_OPEN; // file error 00079 } 00080 return rawdata; 00081 } 00082 00083 00084 RawData::RawData() 00085 : BitmapData(), 00086 d(new RawData::Private(this)) 00087 { 00088 00089 } 00090 00091 00092 RawData::~RawData() 00093 { 00094 delete d; 00095 } 00096 00097 uint16_t RawData::min() 00098 { 00099 return d->min; 00100 } 00101 00102 uint16_t RawData::max() 00103 { 00104 return d->max; 00105 } 00106 00107 void RawData::setMin(uint16_t m) 00108 { 00109 d->min = m; 00110 } 00111 00112 void RawData::setMax(uint16_t m) 00113 { 00114 d->max = m; 00115 } 00116 00117 void RawData::swap(RawData & with) 00118 { 00119 BitmapData::swap(with); 00120 std::swap(this->d, with.d); 00121 } 00122 00123 void * RawData::allocData(const size_t s) 00124 { 00125 void * p = BitmapData::allocData(s); 00126 d->pos = (uint8_t*)p; 00127 d->offset = 0; 00128 return p; 00129 } 00130 00131 00132 void RawData::setDimensions(uint32_t _x, uint32_t _y) 00133 { 00134 BitmapData::setDimensions(_x, _y); 00135 if(d->slices.size()) { 00136 d->sliceWidth = d->slices[0]; 00137 } 00138 else { 00139 d->sliceWidth = _x; 00140 } 00141 } 00142 00143 void RawData::setSlices(const std::vector<uint16_t> & slices) 00144 { 00145 d->slices = slices; 00146 if(slices.size()) { 00147 d->sliceWidth = slices[0]; 00148 } 00149 else { 00150 d->sliceWidth = x(); 00151 } 00152 } 00153 00154 void RawData::setCfaPattern(or_cfa_pattern t) 00155 { 00156 d->cfa_pattern = t; 00157 } 00158 00159 or_cfa_pattern RawData::cfaPattern() 00160 { 00161 return d->cfa_pattern; 00162 } 00163 00164 void RawData::setCompression(uint32_t t) 00165 { 00166 d->compression = t; 00167 } 00168 00169 uint32_t RawData::compression() 00170 { 00171 return d->compression; 00172 } 00173 00174 #if 0 00175 RawData &RawData::append(uint8_t c) 00176 { 00177 assert(d->pos); 00178 assert(d->offset < d->data_size); 00179 *(d->pos) = c; 00180 advance(sizeof(c)); 00181 return *this; 00182 } 00183 #endif 00184 00185 RawData &RawData::append(uint16_t c) 00186 { 00187 assert(d->pos); 00188 assert(d->offset < size()); 00189 *(d->pos) = c & 0xff; 00190 *(d->pos + 1) = (c >> 8) & 0xff; 00191 d->advance(sizeof(c)); 00192 return *this; 00193 } 00194 00195 00196 void RawData::nextRow() 00197 { 00198 d->nextRow(); 00199 } 00200 00201 00202 void RawData::Private::nextRow() 00203 { 00204 uint32_t w = self->x() * 2; 00205 uint32_t row = offset / w; 00206 row++; 00207 if(row == self->y()) 00208 { 00209 // on the last 00210 nextSlice(); 00211 row = 0; 00212 } 00213 offset = row * w + sliceOffset * 2; 00214 pos = (uint8_t*)(self->data()) + offset; 00215 row_offset = offset; 00216 } 00217 00218 void RawData::Private::nextSlice() 00219 { 00220 if(slices.size()) { 00221 sliceOffset += slices[slice]; 00222 slice++; 00223 if(slices.size() > slice) { 00224 sliceWidth = slices[slice]; 00225 } 00226 else { 00227 sliceWidth = 0; 00228 } 00229 } 00230 } 00231 00232 void RawData::Private::advance(size_t s) 00233 { 00234 if(offset + s - row_offset >= sliceWidth * 2) { 00235 nextRow(); 00236 } 00237 else { 00238 pos += s; 00239 offset += s; 00240 } 00241 } 00242 00243 } 00244 /* 00245 Local Variables: 00246 mode:c++ 00247 c-file-style:"stroustrup" 00248 c-file-offsets:((innamespace . 0)) 00249 indent-tabs-mode:nil 00250 fill-column:80 00251 End: 00252 */ 00253