1 #ifndef CAIR_H
2 #define CAIR_H
3 
4 //=========================================================================================================//
5 //CAIR - Content Aware Image Resizer
6 //Copyright (C) 2009 Joseph Auman (brain.recall@gmail.com)
7 
8 //=========================================================================================================//
9 //This library is free software; you can redistribute it and/or
10 //modify it under the terms of the GNU Lesser General Public
11 //License as published by the Free Software Foundation; either
12 //version 2.1 of the License, or (at your option) any later version.
13 //This library is distributed in the hope that it will be useful,
14 //but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //Lesser General Public License for more details.
17 //You should have received a copy of the GNU Lesser General Public
18 //License along with this library; if not, write to the Free Software
19 //Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 
21 //=========================================================================================================//
22 //This thing should hopefully perform the image resize method developed by Shai Avidan and Ariel Shamir.
23 //=========================================================================================================//
24 
25 #include "CAIR_CML.h"
26 
27 //=========================================================================================================//
28 //The default number of threads that will be used for Grayscale, Edge, and Add/Remove operations.
29 //Minimum of 2 required.
30 #define CAIR_NUM_THREADS 4
31 
32 //=========================================================================================================//
33 //Set the number of threads that CAIR should use. Minimum of 2 required.
34 //WARNING: Never call this function while CAIR() is processing an image, otherwise bad things will happen!
35 //Best to set this only once, before any CAIR operations take place.
36 void CAIR_Threads( int thread_count );
37 
38 //=========================================================================================================//
39 //The Great CAIR Frontend. This baby will retarget Source using S_Weights into the dimensions supplied by goal_x and goal_y into D_Weights and Dest.
40 //Weights allows for an area to be biased for removal/protection. A large positive value will protect a portion of the image,
41 //and a large negative value will remove it. Do not exceed the limits of int's, as this will cause an overflow. I would suggest
42 //a safe range of -2,000,000 to 2,000,000 (this is a maximum guideline, much smaller weights will work just as well for most images).
43 //Weights must be the same size as Source. D_Weights will contain the weights of Dest after the resize. Dest is the output,
44 //and as such has no constraints (its contents will be destroyed, just so you know).
45 //The internal order is this: remove horizontal, remove vertical, add horizontal, add vertical.
46 //CAIR can use multiple convolution methods to determine the image energy.
47 //Prewitt and Sobel are close to each other in results and represent the "traditional" edge detection.
48 //V_SQUARE and V1 can produce some of the better quality results, but may remove from large objects to do so. Do note that V_SQUARE
49 //produces much larger edge values, any may require larger weight values (by about an order of magnitude) for effective operation.
50 //Laplacian is a second-derivative operator, and can limit some artifacts while generating others.
51 //CAIR also can use the new improved energy algorithm called "forward energy." Removing seams can sometimes add energy back to the image
52 //by placing nearby edges directly next to each other. Forward energy can get around this by determining the future cost of a seam.
53 //Forward energy removes most serious artifacts from a retarget, but is slightly more costly in terms of performance.
54 enum CAIR_convolution { PREWITT = 0, V1 = 1, V_SQUARE = 2, SOBEL = 3, LAPLACIAN = 4 };
55 enum CAIR_energy { BACKWARD = 0, FORWARD = 1 };
56 bool CAIR( CML_color * Source,
57            CML_int * S_Weights,
58            int goal_x,
59            int goal_y,
60            CAIR_convolution conv,
61            CAIR_energy ener,
62            CML_int * D_Weights,
63            CML_color * Dest,
64            bool (*CAIR_callback)(float) );
65 
66 //=========================================================================================================//
67 //Simple function that generates the grayscale image of Source and places the result in Dest.
68 void CAIR_Grayscale( CML_color * Source, CML_color * Dest );
69 
70 //=========================================================================================================//
71 //Simple function that generates the edge-detection image of Source and stores it in Dest.
72 void CAIR_Edge( CML_color * Source, CAIR_convolution conv, CML_color * Dest );
73 
74 //=========================================================================================================//
75 //Simple function that generates the vertical energy map of Source placing it into Dest.
76 //All values are scaled down to their relative gray value. Weights are assumed all zero.
77 void CAIR_V_Energy( CML_color * Source, CAIR_convolution conv, CAIR_energy ener, CML_color * Dest );
78 
79 //=========================================================================================================//
80 //Simple function that generates the horizontal energy map of Source placing it into Dest.
81 //All values are scaled down to their relative gray value. Weights are assumed all zero.
82 void CAIR_H_Energy( CML_color * Source, CAIR_convolution conv, CAIR_energy ener, CML_color * Dest );
83 
84 //=========================================================================================================//
85 //Experimental
86 //Any area with a negative weight will be removed. This function has three modes, determined by the choice parameter.
87 //AUTO will have the function count the vertical and horizontal rows/columns and remove in the direction that has the least.
88 //VERTICAL will force the function to remove all negative weights in the vertical direction; likewise for HORIZONTAL.
89 //Because some conditions may cause the function not to remove all negative weights in one pass, max_attempts lets the function
90 //go through the removal process as many times as you're willing.
91 enum CAIR_direction { AUTO = 0, VERTICAL = 1, HORIZONTAL = 2 };
92 bool CAIR_Removal( CML_color * Source,
93                    CML_int * S_Weights,
94                    CAIR_direction choice,
95                    int max_attempts,
96                    CAIR_convolution conv,
97                    CAIR_energy ener,
98                    CML_int * D_Weights,
99                    CML_color * Dest,
100                    bool (*CAIR_callback)(float) );
101 
102 //The following Image Map functions are deprecated until better alternatives can be made.
103 #if 0
104 //=========================================================================================================//
105 //Experimental
106 //Precompute removals in the x direction. Map will hold the largest width the corresponding pixel is still visible.
107 //This will calculate all removals down to 3 pixels in width.
108 //Right now this only performs removals and only the x-direction. For the future enlarging is planned. Precomputing for both directions
109 //doesn't work all that well and generates significant artifacts. This function is intended for "content-aware multi-size images" as mentioned
110 //in the doctor's presentation. The next logical step would be to encode Map into an existing image format. Then, using a function like
111 //CAIR_Map_Resize() the image can be resized on a client machine with very little overhead.
112 void CAIR_Image_Map( CML_color * Source, CML_int * Weights, CAIR_convolution conv, CAIR_energy ener, CML_int * Map );
113 
114 //=========================================================================================================//
115 //Experimental
116 //An "example" function on how to decode the Map to quickly resize an image. This is only for the width, since multi-directional
117 //resizing produces significant artifacts. Do note this will produce different results than standard CAIR(), because this resize doesn't
118 //average pixels back into the image as does CAIR(). This function could be multi-threaded much like Remove_Path() for even faster performance.
119 void CAIR_Map_Resize( CML_color * Source, CML_int * Map, int goal_x, CML_color * Dest );
120 #endif
121 
122 //=========================================================================================================//
123 //This works as CAIR, except here maximum quality is attempted. When removing in both directions some amount, CAIR_HD()
124 //will determine which direction has the least amount of energy and then removes in that direction. This is only done
125 //for removal, since enlarging will not benefit, although this function will perform addition just like CAIR().
126 //Inputs are the same as CAIR().
127 bool CAIR_HD( CML_color * Source,
128               CML_int * S_Weights,
129               int goal_x,
130               int goal_y,
131               CAIR_convolution conv,
132               CAIR_energy ener,
133               CML_int * D_Weights,
134               CML_color * Dest,
135               bool (*CAIR_callback)(float) );
136 
137 #endif //CAIR_H
138