// same pixels in consecutive rows
if(last_edge == 0 && idx - m_data[i-1].position > m_width + 1
&& m_data[i].position - idx > m_width)
idx = m_data[i].position - m_width;
else ++idx;
// same pixels in consecutive columns
if(idx%m_width > 2 )
{
int same_length = m_width-1;
int idx_arr = { idx-m_width-2, idx-2, idx+m_width-2 };
for( int j = 0; j < 3; ++j )
{
int location, temp;
search_pixel(idx_arr[j], i, (idx_arr[j]<idx), location);
if(location > 0)
{
temp = m_data[location].position - idx_arr[j];
if(temp < same_length)
same_length = temp;
}
}
if(same_length > 2)
idx += (same_length-2);
}
}
}
printf("%d %d\n", (int)edge, (idx - last_idx));
printf("0 0\n");
}
private:
// set block
void set_block(int index, short value, int position)
{
m_data[index].value = value;
m_data[index].position = position;
}
// search pixel
short search_pixel(int idx, int block, bool bBackward, int& location)
{
if(idx < 1 || idx > m_data[m_count].position)
{
location = -1;
return 0;
}
int i = block;
if(bBackward)
{
for(i = block-1; i >= 0; --i)
if(idx > m_data[i].position)
{
location = i+1;
return m_data[i+1].value;
}
}
else
{
for(i = block; i <= m_count; ++i)
if(idx <= m_data[i].position)
{
location = i;
return m_data[i].value;
}
}
}
// calculate edge
short calculate_edge(int idx, int block)
{
bool flag ; // does neighbor exist
for(int i = 0; i < 8; ++i)
flag[i] = true;
// top
if((idx - 1)/m_width == 0)
flag[0] = flag = flag = false;
// bottom
if(idx + m_width > m_data[m_count].position)
flag = flag = flag = false;
// left (especially when width is 1)
if(m_width == 1 || idx % m_width == 1 )
flag[0] = flag = flag = false;
// right
if(idx % m_width == 0 )
flag = flag = flag = false;
// valid neighbor
short base = m_data[block].value;
short edge = 0;
int nidx; // index of neighbor short
for(int i = 0; i < 8; ++i)
if(flag[i])
{
switch(i)
{
case 0:
case 1:
case 2:
nidx = idx - m_width + i - 1;
break;
case 3:
nidx = idx - 1;
break;
case 4:
nidx = idx + 1;
break;
default:
nidx = idx + m_width + i - 6;
}
short neighbor;
int location;
neighbor = search_pixel(nidx, block, (nidx<idx), location);
short temp = ((neighbor > base) (neighbor - base) : (base - neighbor));
if(temp > edge)
edge = temp;
}
return edge;
}
};
// entry point
int main()
{
CRLEImage image;
while( image.Scan() )
image.Process();
return 0;
}