/* * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * RawTherapee is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ #ifndef __RAWIMAGE_H #define __RAWIMAGE_H #include #include "dcraw.h" #include "imageio.h" namespace rtengine { struct badPix { uint16_t x; uint16_t y; badPix( uint16_t xc, uint16_t yc ): x(xc), y(yc) {} }; class PixelsMap { int w; // line width in base_t units int h; // height typedef unsigned long base_t; static const size_t base_t_size = sizeof(base_t); base_t *pm; public: PixelsMap(int width, int height ) : h(height) { w = (width / (base_t_size * 8)) + 1; pm = new base_t [h * w ]; memset(pm, 0, h * w * base_t_size ); } ~PixelsMap() { delete [] pm; } int width() const { return w; } int height() const { return h; } // if a pixel is set returns true bool get(int x, int y) { return (pm[y * w + x / (base_t_size * 8) ] & (base_t)1 << (x % (base_t_size * 8)) ) != 0; } // set a pixel void set(int x, int y) { pm[y * w + x / (base_t_size * 8) ] |= (base_t)1 << (x % (base_t_size * 8)) ; } // set pixels from a list int set( std::vector &bp) { for(std::vector::iterator iter = bp.begin(); iter != bp.end(); ++iter) { set( iter->x, iter->y); } return bp.size(); } void clear() { memset(pm, 0, h * w * base_t_size ); } // return 0 if at least one pixel in the word(base_t) is set, otherwise return the number of pixels to skip to the next word base_t int skipIfZero(int x, int y) { return pm[y * w + x / (base_t_size * 8) ] == 0 ? base_t_size * 8 - x % (base_t_size * 8) : 0; } }; class RawImage: public DCraw { public: RawImage( const Glib::ustring name ); ~RawImage(); int loadRaw (bool loadData = true, bool closeFile = true, ProgressListener *plistener = 0, double progressRange = 1.0); void get_colorsCoeff( float* pre_mul_, float* scale_mul_, float* cblack_, bool forceAutoWB ); void set_prefilters() { if (isBayer() && get_colors() == 3) { prefilters = filters; filters &= ~((filters & 0x55555555) << 1); } } dcrawImage_t get_image() { return image; } float** compress_image(); // revert to compressed pixels format and release image data float** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column unsigned prefilters; // original filters saved ( used for 4 color processing ) protected: Glib::ustring filename; // complete filename int rotate_deg; // 0,90,180,270 degree of rotation: info taken by dcraw from exif char* profile_data; // Embedded ICC color profile float* allocation; // pointer to allocated memory int maximum_c4[4]; bool isBayer() const { return (filters != 0 && filters != 9); } bool isXtrans() const { return filters == 9; } bool isFoveon() const { return is_foveon; } public: static void initCameraConstants(Glib::ustring baseDir); std::string get_filename() const { return filename; } int get_width() const { return width; } int get_height() const { return height; } int get_iwidth() const { return iwidth; } int get_iheight() const { return iheight; } int get_leftmargin() const { return left_margin; } int get_topmargin() const { return top_margin; } int get_FujiWidth() const { return fuji_width; } eSensorType getSensorType(); void getRgbCam (float rgbcam[3][4]); void getXtransMatrix ( char xtransMatrix[6][6]); void clearXtransCblack( ) { for(int c = 0; c < 4; c++) { cblack[c] = 0; } } unsigned get_filters() const { return filters; } int get_colors() const { return colors; } int get_cblack(int i) const { return cblack[i]; } int get_white(int i) const { if (maximum_c4[0] > 0) { return maximum_c4[i]; } else { return maximum; } } unsigned short get_whiteSample( int r, int c ) const { return white[r][c]; } double get_ISOspeed() const { return iso_speed; } double get_shutter() const { return shutter; } double get_aperture() const { return aperture; } time_t get_timestamp() const { return timestamp; } int get_rotateDegree() const { return rotate_deg; } const std::string get_maker() const { return std::string(make); } const std::string get_model() const { return std::string(model); } float get_cam_mul(int c )const { return cam_mul[c]; } float get_pre_mul(int c )const { return pre_mul[c]; } float get_rgb_cam( int r, int c) const { return rgb_cam[r][c]; } int get_exifBase() const { return exif_base; } int get_ciffBase() const { return ciff_base; } int get_ciffLen() const { return ciff_len; } int get_profileLen() const { return profile_length; } char* get_profile() const { return profile_data; } IMFILE *get_file() { return ifp; } bool is_supportedThumb() const ; bool is_jpegThumb() const ; bool is_ppmThumb() const ; int get_thumbOffset() { return int(thumb_offset); } int get_thumbWidth() { return int(thumb_width); } int get_thumbHeight() { return int(thumb_height); } int get_thumbBPS() { return thumb_load_raw ? 16 : 8; } bool get_thumbSwap() const; unsigned get_thumbLength() { return thumb_length; } bool zeroIsBad() { return zero_is_bad == 1 ? true : false; } public: // dcraw functions void scale_colors() { if(isXtrans()) { clearXtransCblack( ); } DCraw::scale_colors(); } void pre_interpolate() { DCraw::pre_interpolate(); } public: bool ISRED (unsigned row, unsigned col) const { return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) == 0); } bool ISGREEN(unsigned row, unsigned col) const { return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) == 1); } bool ISBLUE (unsigned row, unsigned col) const { return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) == 2); } unsigned FC (unsigned row, unsigned col) const { return (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3); } bool ISXTRANSRED (unsigned row, unsigned col) const { return ((xtrans[(row) % 6][(col) % 6]) == 0); } bool ISXTRANSGREEN(unsigned row, unsigned col) const { return ((xtrans[(row) % 6][(col) % 6]) == 1); } bool ISXTRANSBLUE (unsigned row, unsigned col) const { return ((xtrans[(row) % 6][(col) % 6]) == 2); } unsigned XTRANSFC (unsigned row, unsigned col) const { return (xtrans[(row) % 6][(col) % 6]); } }; } #endif // __RAWIMAGE_H