Use qdx to infer padding.
The border is unused for now. I set padding to a specific color.
This commit is contained in:
		
							parent
							
								
									43208cea90
								
							
						
					
					
						commit
						593352bc45
					
				
					 2 changed files with 238 additions and 95 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -9,7 +9,7 @@ SRC       = rotation.cpp \
 | 
				
			||||||
HEADERS   = image.h \
 | 
					HEADERS   = image.h \
 | 
				
			||||||
	    pnm.h
 | 
						    pnm.h
 | 
				
			||||||
OBJS      = $(patsubst %.cpp,%.o,$(SRC))
 | 
					OBJS      = $(patsubst %.cpp,%.o,$(SRC))
 | 
				
			||||||
IMG       = img/lena_3000.pgm
 | 
					IMG       = img/lena_64.pgm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: $(OBJS)
 | 
					all: $(OBJS)
 | 
				
			||||||
	$(CXX) $(CXXFLAGS) $(LFLAGS) $(OBJS) -o $(BUILD_DIR)/rotation
 | 
						$(CXX) $(CXXFLAGS) $(LFLAGS) $(OBJS) -o $(BUILD_DIR)/rotation
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										313
									
								
								rotation.cpp
									
										
									
									
									
								
							
							
						
						
									
										313
									
								
								rotation.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -161,104 +161,184 @@ bool fequal(float a, float b, float sigma)
 | 
				
			||||||
// Padding
 | 
					// Padding
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t* generate_padding_table(Image const& src,
 | 
					uint16_t* generate_padding_table(Image const& rotated,
 | 
				
			||||||
                                Image const& rotated,
 | 
					                                 Point src_rotated_origin,
 | 
				
			||||||
                                double rotation,
 | 
					                                 Point const& qdx, Point const& qdy,
 | 
				
			||||||
                                int q_pos)
 | 
					                                 int src_qwidth, int src_qheight)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uint16_t* padding_table = new uint16_t[rotated.height];
 | 
					  uint16_t* padding_table = new uint16_t[rotated.height];
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // We suppose the image is square.
 | 
					  // We suppose the image is square.
 | 
				
			||||||
  double const sigma = 1.0e-5;
 | 
					  if (qdx.x == 0 || qdx.y == 0)
 | 
				
			||||||
  if (fequal(rotation, 0, sigma)
 | 
					 | 
				
			||||||
      || fequal(rotation, M_PI / 2, sigma)
 | 
					 | 
				
			||||||
      || fequal(rotation, M_PI, sigma)
 | 
					 | 
				
			||||||
      || fequal(rotation, 3 * M_PI / 2, sigma))
 | 
					 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    memset(padding_table, 0, sizeof (uint16_t) * rotated.height);
 | 
					    memset(padding_table, 0, sizeof (uint16_t) * rotated.height);
 | 
				
			||||||
    return padding_table;
 | 
					    return padding_table;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  double padding_rotation = 0.0;
 | 
					  for (unsigned int i = 0; i < rotated.height; ++i)
 | 
				
			||||||
  if (rotation < M_PI / 2)
 | 
					 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    padding_rotation = rotation;
 | 
					    int y_range = 0;
 | 
				
			||||||
  } else if (rotation < M_PI)
 | 
					    if (src_rotated_origin.y < 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    padding_rotation = rotation - M_PI / 2;
 | 
					      y_range = ceil((-src_rotated_origin.y) / (float) qdx.y);
 | 
				
			||||||
  } else if (rotation < 3 * M_PI / 2)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    padding_rotation = rotation - M_PI;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else
 | 
					    else if (src_rotated_origin.y >= src_qheight)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    padding_rotation = rotation - 3 * M_PI / 2;
 | 
					      y_range = ceil((float) (src_rotated_origin.y - src_qheight + 1) / (float) (-qdx.y));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (y_range < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      cout << "Negative Y range" << endl;
 | 
				
			||||||
 | 
					      abort();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Quantized delta for padding
 | 
					    int x_range = 0;
 | 
				
			||||||
  // TODO: we should be able to infer these values from qdx and qdy
 | 
					    if (src_rotated_origin.x < 0)
 | 
				
			||||||
  DPoint const top_left_grid = get_mapped_point(src, Point(0, 0), padding_rotation);
 | 
					 | 
				
			||||||
  Point const top_left = convert_img_coord(rotated, top_left_grid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DPoint const top_right_grid = get_mapped_point(src, Point(src.width - 1, 0), padding_rotation);
 | 
					 | 
				
			||||||
  DPoint const top_right = convert_img_coord_precision(rotated, top_right_grid);
 | 
					 | 
				
			||||||
  Point const q_top_right(top_right.x * q_pos, top_right.y * q_pos);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DPoint const bottom_left_grid = get_mapped_point(src, Point(0, src.height), padding_rotation);
 | 
					 | 
				
			||||||
  DPoint const bottom_left = convert_img_coord_precision(rotated, bottom_left_grid);
 | 
					 | 
				
			||||||
  Point const q_bottom_left(bottom_left.x * q_pos, bottom_left.y * q_pos);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int i = 0;
 | 
					 | 
				
			||||||
  int const q_top_width = q_top_right.x;
 | 
					 | 
				
			||||||
  int const q_top_step = q_top_width / top_left.y;
 | 
					 | 
				
			||||||
  int previous_padding = 0;
 | 
					 | 
				
			||||||
  for (; i <= top_left.y; ++i)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    padding_table[i] = (q_top_width - i * q_top_step) / q_pos;
 | 
					      x_range = ceil((-src_rotated_origin.x) / (float) qdx.x);
 | 
				
			||||||
    previous_padding = padding_table[i];
 | 
					    }
 | 
				
			||||||
 | 
					    else if (src_rotated_origin.x >= src_qwidth)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      x_range = ceil((float) (src_rotated_origin.x - src_qwidth + 1) / (float) (-qdx.x));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (x_range < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      cout << "Negative X range" << endl;
 | 
				
			||||||
 | 
					      abort();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int const remaining_height = rotated.height - 1 - i;
 | 
					    padding_table[i] = max(x_range, y_range);
 | 
				
			||||||
  int const q_bottom_width = q_bottom_left.x;
 | 
					
 | 
				
			||||||
  int const q_bottom_step = q_bottom_width / remaining_height;
 | 
					 | 
				
			||||||
  int remaining_index = 1;
 | 
					 | 
				
			||||||
  for (; i < (int) rotated.height; ++i, ++remaining_index)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    padding_table[i] = min((unsigned int) (remaining_index * q_bottom_step) / q_pos,
 | 
					      Point test(src_rotated_origin.x + padding_table[i] * qdx.x,
 | 
				
			||||||
                           (unsigned int) rotated.height - 1 - padding_table[rotated.height - 1 - i]);
 | 
					                 src_rotated_origin.y + padding_table[i] * qdx.y);
 | 
				
			||||||
 | 
					      if (test.x < 0 || test.y < 0
 | 
				
			||||||
 | 
					         || test.x >= src_qwidth || test.y >= src_qheight)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        cout << "Padding issue at line " << i << endl;
 | 
				
			||||||
 | 
					        cout << "  src:    " << src_rotated_origin << endl;
 | 
				
			||||||
 | 
					        cout << "  test:   " << test << endl;
 | 
				
			||||||
 | 
					        cout << "  q dim:  " << src_qwidth << " x " << src_qheight << endl;
 | 
				
			||||||
 | 
					        cout << "  " << padding_table[i] << " x " << qdx << endl;
 | 
				
			||||||
 | 
					        cout << "  x diff = " << src_rotated_origin.x - src_qwidth + 1 << endl;
 | 
				
			||||||
 | 
					        cout << "  x coef = " << (float) (src_rotated_origin.x - src_qwidth + 1) / (float) (-qdx.x) << endl;
 | 
				
			||||||
 | 
					        abort();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    src_rotated_origin += qdy;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return padding_table;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t* generate_padding_table_back_q(Image const& rotated,
 | 
				
			||||||
 | 
					                                        Point src_rotated_origin,
 | 
				
			||||||
 | 
					                                        Point const& qdx,
 | 
				
			||||||
 | 
					                                        Point const& qdy,
 | 
				
			||||||
 | 
					                                        int src_qwidth,
 | 
				
			||||||
 | 
					                                        int src_qheight,
 | 
				
			||||||
 | 
					                                        uint16_t const* front_padding)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  uint16_t* padding_table = new uint16_t[rotated.height];
 | 
				
			||||||
 | 
					  // We suppose the image is square.
 | 
				
			||||||
 | 
					  if (qdx.x == 0 || qdx.y == 0)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    memset(padding_table, 0, sizeof (uint16_t) * rotated.height);
 | 
				
			||||||
 | 
					    return padding_table;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  src_rotated_origin.x = (rotated.width - 1) * qdx.x;
 | 
				
			||||||
 | 
					  src_rotated_origin.y = (rotated.width - 1) * qdx.y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (unsigned int i = 0; i < rotated.height; ++i)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int y_range = 0;
 | 
				
			||||||
 | 
					    if (src_rotated_origin.y < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      y_range = ceil((-src_rotated_origin.y) / (float) qdx.y);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (src_rotated_origin.y >= src_qheight)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      y_range = ceil((float) (src_rotated_origin.y - src_qheight + 1) / (float) (qdx.y));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (y_range < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      cout << "Negative back Y range at line " << i << endl;
 | 
				
			||||||
 | 
					      abort();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int x_range = 0;
 | 
				
			||||||
 | 
					    if (src_rotated_origin.x < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      x_range = ceil((-src_rotated_origin.x) / (float) qdx.x);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (src_rotated_origin.x >= src_qwidth)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      x_range = ceil((float) (src_rotated_origin.x - src_qwidth + 1) / abs(qdx.x));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (x_range < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      cout << "Negative back X range at line " << i << endl;
 | 
				
			||||||
 | 
					      cout << "  src origin: " << src_rotated_origin << endl;
 | 
				
			||||||
 | 
					      cout << "  q dim:      " << src_qwidth << " x " << src_qheight << endl;
 | 
				
			||||||
 | 
					      abort();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    padding_table[i] = max(x_range, y_range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      Point test(src_rotated_origin.x - padding_table[i] * qdx.x,
 | 
				
			||||||
 | 
					                 src_rotated_origin.y - padding_table[i] * qdx.y);
 | 
				
			||||||
 | 
					      if (test.x < 0 || test.y < 0
 | 
				
			||||||
 | 
					         || test.x >= src_qwidth || test.y >= src_qheight)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        padding_table[i] = rotated.width - front_padding[i];
 | 
				
			||||||
 | 
					//        cout << "Back padding issue at line " << i << endl;
 | 
				
			||||||
 | 
					//        cout << "  src origin: " << src_rotated_origin << endl;
 | 
				
			||||||
 | 
					//        cout << "  test:       " << test << endl;
 | 
				
			||||||
 | 
					//        cout << "  q dim:      " << src_qwidth << " x " << src_qheight << endl;
 | 
				
			||||||
 | 
					//        cout << "  " << padding_table[i] << " x " << qdx << endl;
 | 
				
			||||||
 | 
					//        cout << "  X range     " << x_range << endl;
 | 
				
			||||||
 | 
					//        cout << "  Y range     " << y_range << endl;
 | 
				
			||||||
 | 
					//        cout << "    height diff = " << src_rotated_origin.y - src_qheight + 1 << endl;
 | 
				
			||||||
 | 
					//        cout << "    coef = " << (float) (src_rotated_origin.y - src_qheight + 1) / (float) qdx.y << endl;
 | 
				
			||||||
 | 
					//        abort();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    src_rotated_origin += qdy;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return padding_table;
 | 
					  return padding_table;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void print_padding_table(uint16_t const* padding_table,
 | 
					void print_padding_table(uint16_t const* padding_table,
 | 
				
			||||||
                         uint16_t const* border_table,
 | 
					                         uint16_t const* border_table,
 | 
				
			||||||
                         unsigned int size)
 | 
					                         Image const& image)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  cout << "Padding table:" << endl;
 | 
					  cout << "Padding table:" << endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (unsigned int i = 0; i < size; ++i)
 | 
					  for (unsigned int i = 0; i < image.height; ++i)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    int left_padding = padding_table[i];
 | 
					    int left_padding = padding_table[i];
 | 
				
			||||||
    int left_border = border_table[i];
 | 
					    int left_border = border_table[i];
 | 
				
			||||||
    int right_padding = padding_table[size - 1 - i];
 | 
					    int right_padding = padding_table[image.height - 1 - i];
 | 
				
			||||||
    int right_border = border_table[size - 1 - i];
 | 
					    int right_border = border_table[image.height - 1 - i];
 | 
				
			||||||
    int core_pixels = size - left_padding - right_padding - left_border - right_border;
 | 
					    int core_pixels = image.width - left_padding - right_padding - left_border - right_border;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (core_pixels < 0)
 | 
					    if (core_pixels < 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      cout << "Too much padding + border at line " << i << endl;
 | 
					      cout << "Too much padding + border at line " << i << endl;
 | 
				
			||||||
      cout << "  left padding  = " << left_padding << endl;
 | 
					      cout << "  left padding  = " << left_padding << endl;
 | 
				
			||||||
      cout << "  left border   = " << left_border << endl;
 | 
					      cout << "  left border   = " << left_border << endl;
 | 
				
			||||||
      cout << "  right padding = " << right_padding << endl;
 | 
					 | 
				
			||||||
      cout << "  right border  = " << right_border << endl;
 | 
					      cout << "  right border  = " << right_border << endl;
 | 
				
			||||||
 | 
					      cout << "  right padding = " << right_padding << endl;
 | 
				
			||||||
      cout << "  total         = " << left_padding + left_border + right_border + right_padding << endl;
 | 
					      cout << "  total         = " << left_padding + left_border + right_border + right_padding << endl;
 | 
				
			||||||
      cout << "  max size      = " << size << endl;
 | 
					      cout << "  width         = " << image.width << endl;
 | 
				
			||||||
      abort();
 | 
					      abort();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cout << "  [";
 | 
					    cout << "  " << i << " [";
 | 
				
			||||||
    for (int j = 0; j < left_padding; ++j)
 | 
					    for (int j = 0; j < left_padding; ++j)
 | 
				
			||||||
      cout << " ";
 | 
					      cout << " ";
 | 
				
			||||||
    for (int j = 0; j < left_border; ++j)
 | 
					    for (int j = 0; j < left_border; ++j)
 | 
				
			||||||
| 
						 | 
					@ -280,39 +360,68 @@ void print_padding_table(uint16_t const* padding_table,
 | 
				
			||||||
// Border
 | 
					// Border
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t* generate_border_table(uint16_t const* padding_table, int size)
 | 
					uint16_t* generate_border_table(uint16_t const* padding_table, Image const& image)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uint16_t* border_table = new uint16_t[size];
 | 
					  uint16_t* border_table = new uint16_t[image.height];
 | 
				
			||||||
 | 
					  if (image.width - padding_table[0] - padding_table[image.height - 1] == 0)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    cout << "No room for top border" << endl;
 | 
				
			||||||
    border_table[0] = 0;
 | 
					    border_table[0] = 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    border_table[0] = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 1; i < size - 1; ++i)
 | 
					  for (unsigned int i = 1; i < image.height - 1; ++i)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    if (padding_table[i - 1] > padding_table[i])
 | 
					    if (padding_table[i] == padding_table[i - 1])
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      border_table[i] = padding_table[i - 1] - padding_table[i];
 | 
					      border_table[i] = 1;
 | 
				
			||||||
      if (padding_table[i - 1] != padding_table[i])
 | 
					 | 
				
			||||||
        border_table[i] += 1;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      if (padding_table[i - 1] > padding_table[i])
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        border_table[i] = padding_table[i - 1] - padding_table[i] + 1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        border_table[i - 1] = padding_table[i] - padding_table[i - 1] + 1;
 | 
				
			||||||
        border_table[i] = 1;
 | 
					        border_table[i] = 1;
 | 
				
			||||||
      if (padding_table[i - 1] != padding_table[i])
 | 
					      }
 | 
				
			||||||
        border_table[i - 1] += 1;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Check that we don't add too much border
 | 
					  // Check that we don't add too much border
 | 
				
			||||||
  for (int i = 1; i < size - 1; ++i)
 | 
					  for (unsigned int i = 1; i < image.height - 1; ++i)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    if (padding_table[i] + border_table[i]
 | 
					    if (padding_table[i] + border_table[i]
 | 
				
			||||||
      + padding_table[size - 1 - i] + border_table[size - 1 - i]
 | 
					      + padding_table[image.height - 1 - i] + border_table[image.height - 1 - i]
 | 
				
			||||||
      > size)
 | 
					      > (int) image.width)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					      cout << "Too much border!" << endl;
 | 
				
			||||||
 | 
					      cout << "  border[" << i << "]: " << border_table[i] << endl;
 | 
				
			||||||
 | 
					      cout << "  border[" << image.height - 1 - i << "]: " << border_table[image.height - 1 - i] << endl;
 | 
				
			||||||
 | 
					      if (border_table[i] > border_table[image.height - 1 - i])
 | 
				
			||||||
        border_table[i] -= 1;
 | 
					        border_table[i] -= 1;
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        border_table[image.height - 1 - i] -= 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  border_table[size - 1] = size - padding_table[0] - padding_table[size - 1];
 | 
					  border_table[image.height - 1] = image.width - padding_table[0] - padding_table[image.height - 1] - border_table[0];
 | 
				
			||||||
 | 
					  if (border_table[image.height - 1] > image.width)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    cout << "That shit cray" << endl;
 | 
				
			||||||
 | 
					    cout << "  width = " << image.width << endl;
 | 
				
			||||||
 | 
					    cout << "  left padding = " << padding_table[0] << endl;
 | 
				
			||||||
 | 
					    cout << "  left border = " << border_table[0] << endl;
 | 
				
			||||||
 | 
					    cout << "  right border = " << border_table[image.height - 1] << endl;
 | 
				
			||||||
 | 
					    cout << "  right padding = " << padding_table[image.height - 1] << endl;
 | 
				
			||||||
 | 
					    cout << "  ~ " << image.width << endl;
 | 
				
			||||||
 | 
					    cout << "  ~ " << image.width - padding_table[0] << endl;
 | 
				
			||||||
 | 
					    cout << "  ~ " << image.width - padding_table[0] - padding_table[image.height - 1] << endl;
 | 
				
			||||||
 | 
					    cout << "  ~ " << image.width - padding_table[0] - padding_table[image.height - 1] - border_table[0] << endl;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return border_table;
 | 
					  return border_table;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -329,7 +438,7 @@ void rotate_pixel(Image const& src,
 | 
				
			||||||
                  Point const& src_rotated_point,
 | 
					                  Point const& src_rotated_point,
 | 
				
			||||||
                  unsigned int const src_limit,
 | 
					                  unsigned int const src_limit,
 | 
				
			||||||
                  pvalue_t* rotate_buffer, unsigned int rot_index,
 | 
					                  pvalue_t* rotate_buffer, unsigned int rot_index,
 | 
				
			||||||
                  unsigned int q_pow)
 | 
					                  int q_pow)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // Quantize on a 8x8 grid
 | 
					  // Quantize on a 8x8 grid
 | 
				
			||||||
  int const q_inter_pow = 3;
 | 
					  int const q_inter_pow = 3;
 | 
				
			||||||
| 
						 | 
					@ -428,44 +537,76 @@ Image* rotate(Image const& src, double angle)
 | 
				
			||||||
  unsigned int const src_limit = src.width * src.height * src.pixel_size;
 | 
					  unsigned int const src_limit = src.width * src.height * src.pixel_size;
 | 
				
			||||||
  int const width = rotated->width;
 | 
					  int const width = rotated->width;
 | 
				
			||||||
  int const height = rotated->height;
 | 
					  int const height = rotated->height;
 | 
				
			||||||
 | 
					  int const& src_qwidth = src.width * q_pos;
 | 
				
			||||||
 | 
					  int const& src_qheight = src.height * q_pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Point src_rotated_origin(rot_origin_in_src.x * q_pos,
 | 
					  Point src_rotated_origin(rot_origin_in_src.x * q_pos + q_pos / 2,
 | 
				
			||||||
                           rot_origin_in_src.y * q_pos);
 | 
					                           rot_origin_in_src.y * q_pos + q_pos / 2);
 | 
				
			||||||
  // Padding
 | 
					  // Padding
 | 
				
			||||||
  uint16_t* padding_table = generate_padding_table(src, *rotated, rotation, q_pos);
 | 
					  uint16_t* padding_table = generate_padding_table(*rotated, src_rotated_origin,
 | 
				
			||||||
  uint16_t* border_table = generate_border_table(padding_table, rotated->height);
 | 
					                                                   qdx, qdy,
 | 
				
			||||||
  //print_padding_table(padding_table, border_table, height, true);
 | 
					                                                   src_qwidth, src_qheight);
 | 
				
			||||||
 | 
					 // uint16_t* back_padding_table = generate_padding_table_back_q(*rotated, src_rotated_origin,
 | 
				
			||||||
 | 
					 //                                                              qdx, qdy,
 | 
				
			||||||
 | 
					 //                                                              src_qwidth, src_qheight,
 | 
				
			||||||
 | 
					 //                                                              padding_table);
 | 
				
			||||||
 | 
					  //uint16_t* border_table = generate_border_table(padding_table, *rotated);
 | 
				
			||||||
 | 
					  //print_padding_table(padding_table, border_table, *rotated);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int y = 0; y < height; ++y)
 | 
					  for (int y = 0; y < height; ++y)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Point src_rotated_point = src_rotated_origin;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: compact these structure to increase locality
 | 
					    // TODO: compact these structure to increase locality
 | 
				
			||||||
    int const left_padding = padding_table[y];
 | 
					    int const left_padding = padding_table[y];
 | 
				
			||||||
    int const left_border = border_table[y];
 | 
					    int const left_border = 0;
 | 
				
			||||||
    int const right_padding = padding_table[height - 1 - y];
 | 
					    int const right_padding = 0;
 | 
				
			||||||
    int const right_border = border_table[height - 1 - y];
 | 
					    int const right_border = padding_table[height - 1 - y];
 | 
				
			||||||
    int const core_pixels = width - left_padding - left_border - right_border - right_padding;
 | 
					    int const core_pixels = width - left_padding - left_border - right_border - right_padding;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Left padding
 | 
					    // Left padding
 | 
				
			||||||
    for (int x = 0; x < left_padding; ++x, ++buffer_index)
 | 
					    for (int x = 0; x < left_padding; ++x, ++buffer_index)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      // Set to black value
 | 
					      // Set to black value
 | 
				
			||||||
      buffer[buffer_index] = 0;
 | 
					      // TODO: memset
 | 
				
			||||||
      src_rotated_point += qdx;
 | 
					      buffer[buffer_index] = 50;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Border
 | 
					    // Border
 | 
				
			||||||
    for (int x = 0; x < left_border; ++x, ++buffer_index)
 | 
					    for (int x = 0; x < left_border; ++x, ++buffer_index)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      buffer[buffer_index] = 0; // TODO: handle border
 | 
					      buffer[buffer_index] = 0; // TODO: handle border
 | 
				
			||||||
      src_rotated_point += qdx;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Point src_rotated_point(src_rotated_origin.x + (left_padding + left_border) * qdx.x,
 | 
				
			||||||
 | 
					                            src_rotated_origin.y + (left_padding + left_border) * qdx.y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Body
 | 
					    // Body
 | 
				
			||||||
    for (int x = 0; x < core_pixels; ++x, ++buffer_index)
 | 
					    for (int x = 0; x < core_pixels; ++x, ++buffer_index)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (src_rotated_point.x < 0 || src_rotated_point.y < 0
 | 
				
			||||||
 | 
					          || src_rotated_point.x >= src_qwidth || src_rotated_point.y >= src_qheight)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					//        cout << "Point too low!" << endl;
 | 
				
			||||||
 | 
					//        cout << "  x: " << x << endl;
 | 
				
			||||||
 | 
					//        cout << "  src_rotated_point: " << src_rotated_point << endl;
 | 
				
			||||||
 | 
					//        cout << "  qdx: " << qdx << endl;
 | 
				
			||||||
 | 
					//        cout << "  q_pos: " << q_pos << endl;
 | 
				
			||||||
 | 
					//        cout << "  rotated point: (" << x + left_padding + left_border << ", " << y << ")" << endl;
 | 
				
			||||||
 | 
					//        cout << "  src point: (" << (src_rotated_point.x >> q_pos_pow) << ", " << (src_rotated_point.y >> q_pos_pow) << ")" << endl;
 | 
				
			||||||
 | 
					//        cout << "  src point: (" << (src_rotated_point.x / q_pos) << ", " << (src_rotated_point.y / q_pos) << ")" << endl;
 | 
				
			||||||
 | 
					//        cout << "  width: " << width << endl;
 | 
				
			||||||
 | 
					//        cout << "  left padding: " << left_padding << endl;
 | 
				
			||||||
 | 
					//        cout << "   left border: " << left_border << endl;
 | 
				
			||||||
 | 
					//        cout << "    core pixels: " << core_pixels << endl;
 | 
				
			||||||
 | 
					//        cout << "   right border: " << right_border << endl;
 | 
				
			||||||
 | 
					//        cout << "  right padding: " << right_padding << endl;
 | 
				
			||||||
 | 
					        buffer[buffer_index] = 255;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        rotate_pixel(src, src_rotated_point, src_limit, buffer, buffer_index, q_pos_pow);
 | 
					        rotate_pixel(src, src_rotated_point, src_limit, buffer, buffer_index, q_pos_pow);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      src_rotated_point += qdx;
 | 
					      src_rotated_point += qdx;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -480,11 +621,13 @@ Image* rotate(Image const& src, double angle)
 | 
				
			||||||
    for (int x = 0; x < right_padding; ++x, ++buffer_index)
 | 
					    for (int x = 0; x < right_padding; ++x, ++buffer_index)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      // Set to black value
 | 
					      // Set to black value
 | 
				
			||||||
      buffer[buffer_index] = 0;
 | 
					      // TODO: memset
 | 
				
			||||||
 | 
					      buffer[buffer_index] = 100;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    src_rotated_origin += qdy;
 | 
					    src_rotated_origin += qdy;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					//  cout << endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return rotated;
 | 
					  return rotated;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -798,9 +941,9 @@ int main(int argc, char* argv[])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  double const step = 15;
 | 
					  double const step = 5;
 | 
				
			||||||
  bool save_output_img = false;
 | 
					  bool save_output_img = true;
 | 
				
			||||||
  bool print_each_run = false;
 | 
					  bool print_each_run = true;
 | 
				
			||||||
  bool test_tile = false;
 | 
					  bool test_tile = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // No tile
 | 
					  // No tile
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue