// Copyright (C) 2007 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_DNG_SHAREd_ #define DLIB_DNG_SHAREd_ #include "../pixel.h" #include #include "../uintn.h" namespace dlib { namespace dng_helpers_namespace { enum { grayscale = 1, rgb, hsi, rgb_paeth, rgb_alpha, rgb_alpha_paeth, grayscale_16bit, grayscale_float }; const unsigned long dng_magic_byte = 100; template rgb_pixel predictor_rgb_paeth (const T& img, long row, long col) /* This is similar to the Paeth filter from the PNG image format. */ { // a = left, b = above, c = upper left rgb_pixel a(0,0,0), b(0,0,0), c(0,0,0); const long c1 = col-1; const long r1 = row-1; if (c1 >= 0) assign_pixel(a, img[row][c1]); else assign_pixel(a,(unsigned char)0); if (c1 >= 0 && r1 >= 0) assign_pixel(c, img[r1][c1]); else assign_pixel(c,(unsigned char)0); if (r1 >= 0) assign_pixel(b, img[r1][col]); else assign_pixel(b,(unsigned char)0); rgb_pixel p; p.red = a.red + b.red - c.red; p.green = a.green + b.green - c.green; p.blue = a.blue + b.blue - c.blue; short pa = std::abs((short)p.red - (short)a.red) + std::abs((short)p.green - (short)a.green) + std::abs((short)p.blue - (short)a.blue); short pb = std::abs((short)p.red - (short)b.red) + std::abs((short)p.green - (short)b.green) + std::abs((short)p.blue - (short)b.blue); short pc = std::abs((short)p.red - (short)c.red) + std::abs((short)p.green - (short)c.green) + std::abs((short)p.blue - (short)c.blue); if (pa <= pb && pa <= pc) return a; else if (pb <= pc) return b; else return c; } template rgb_pixel predictor_rgb (const T& img, long row, long col) { // a = left, b = above, c = upper left rgb_pixel a(0,0,0), b(0,0,0), c(0,0,0); const long c1 = col-1; const long r1 = row-1; if (c1 >= 0) assign_pixel(a, img[row][c1]); else assign_pixel(a,(unsigned char)0); if (c1 >= 0 && r1 >= 0) assign_pixel(c, img[r1][c1]); else assign_pixel(c,(unsigned char)0); if (r1 >= 0) assign_pixel(b, img[r1][col]); else assign_pixel(b,(unsigned char)0); rgb_pixel p; p.red = a.red + b.red - c.red; p.green = a.green + b.green - c.green; p.blue = a.blue + b.blue - c.blue; return p; } template rgb_alpha_pixel predictor_rgb_alpha_paeth (const T& img, long row, long col) /* This is similar to the Paeth filter from the PNG image format. */ { // a = left, b = above, c = upper left rgb_alpha_pixel a, b, c; const long c1 = col-1; const long r1 = row-1; if (c1 >= 0) assign_pixel(a, img[row][c1]); else assign_pixel(a,(unsigned char)0); if (c1 >= 0 && r1 >= 0) assign_pixel(c, img[r1][c1]); else assign_pixel(c,(unsigned char)0); if (r1 >= 0) assign_pixel(b, img[r1][col]); else assign_pixel(b,(unsigned char)0); rgb_alpha_pixel p; p.red = a.red + b.red - c.red; p.green = a.green + b.green - c.green; p.blue = a.blue + b.blue - c.blue; short pa = std::abs((short)p.red - (short)a.red) + std::abs((short)p.green - (short)a.green) + std::abs((short)p.blue - (short)a.blue); short pb = std::abs((short)p.red - (short)b.red) + std::abs((short)p.green - (short)b.green) + std::abs((short)p.blue - (short)b.blue); short pc = std::abs((short)p.red - (short)c.red) + std::abs((short)p.green - (short)c.green) + std::abs((short)p.blue - (short)c.blue); if (pa <= pb && pa <= pc) return a; else if (pb <= pc) return b; else return c; } template rgb_alpha_pixel predictor_rgb_alpha (const T& img, long row, long col) { // a = left, b = above, c = upper left rgb_alpha_pixel a, b, c; const long c1 = col-1; const long r1 = row-1; if (c1 >= 0) assign_pixel(a, img[row][c1]); else assign_pixel(a,(unsigned char)0); if (c1 >= 0 && r1 >= 0) assign_pixel(c, img[r1][c1]); else assign_pixel(c,(unsigned char)0); if (r1 >= 0) assign_pixel(b, img[r1][col]); else assign_pixel(b,(unsigned char)0); rgb_alpha_pixel p; p.red = a.red + b.red - c.red; p.green = a.green + b.green - c.green; p.blue = a.blue + b.blue - c.blue; p.alpha = a.alpha + b.alpha - c.alpha; return p; } template hsi_pixel predictor_hsi (const T& img, long row, long col) { // a = left, b = above, c = upper left hsi_pixel a(0,0,0), b(0,0,0), c(0,0,0); const long c1 = col-1; const long r1 = row-1; if (c1 >= 0) assign_pixel(a, img[row][c1]); else assign_pixel(a,(unsigned char)0); if (c1 >= 0 && r1 >= 0) assign_pixel(c, img[r1][c1]); else assign_pixel(c,(unsigned char)0); if (r1 >= 0) assign_pixel(b, img[r1][col]); else assign_pixel(b,(unsigned char)0); hsi_pixel p; p.h = a.h + b.h - c.h; p.s = a.s + b.s - c.s; p.i = a.i + b.i - c.i; return p; } template unsigned char predictor_grayscale (const T& img, long row, long col) { // a = left, b = above, c = upper left unsigned char a = 0, b = 0, c = 0; const long c1 = col-1; const long r1 = row-1; if (c1 >= 0) assign_pixel(a, img[row][c1]); if (c1 >= 0 && r1 >= 0) assign_pixel(c, img[r1][c1]); if (r1 >= 0) assign_pixel(b, img[r1][col]); unsigned char p = a + b - c; return p; } template uint16 predictor_grayscale_16 (const T& img, long row, long col) { // a = left, b = above, c = upper left uint16 a = 0, b = 0, c = 0; const long c1 = col-1; const long r1 = row-1; if (c1 >= 0) assign_pixel(a, img[row][c1]); if (c1 >= 0 && r1 >= 0) assign_pixel(c, img[r1][c1]); if (r1 >= 0) assign_pixel(b, img[r1][col]); uint16 p = a + b - c; return p; } } } #endif // DLIB_DNG_SHAREd_