// -*- C++ -*- // Copyright 2006 Deutsches Forschungszentrum fuer Kuenstliche Intelligenz // or its licensors, as applicable. // // You may not use this file except under the terms of the accompanying license. // // Licensed under the Apache License, Version 2.0 (the "License"); you // may not use this file except in compliance with the License. You may // obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Project: // File: // Purpose: // Responsible: tmb // Reviewer: // Primary Repository: // Web Sites: #ifndef h_grid_ #define h_grid_ #include "colib.h" #include "imgio.h" using namespace iulib; namespace ocropus { class Grid { private: colib::bytearray data; // current position int x,y; // height of current line in grid // (i.e. the height of largest subimage added in current line) int hmax; // number of components (number of subimages in the grid) int ncomp; public: // standard contructor just initializes members Grid() { x = 0; y = 1; hmax = 0; ncomp = 0; } void create(int width=4800,int height=800) { data.resize(width,height); // init data with "background", maybe we should have // sth like #def BG 0/1 and, of course, store in pBm fill(data, 255); x = 0; y = 1; hmax = 0; ncomp = 0; } /** * resize(): needed to add/append extra subimages to loaded grids that * were cropped when saved. Adding only to the height of grid doesn't * upset structure. */ void resize(int height) { if (height < data.dim(1)) return; //fprintf(stderr,"%d\n",height); colib::bytearray tmp; move(tmp, data); //fprintf(stderr,"%d %d\n",tmp.dim(0),tmp.dim(1)); data.resize(data.dim(0),height); fill(data, 255); for(int i=0;i=0; j--) { if(data(0,j)==0) { hmax=j; break; } } } y += hmax+1; x = 0; hmax=0; } /** * add a subimage to the grid * current error handling: * - if subimage is too wide -> throw exception * - if subimage it too high -> return false * the two cases should be handled the same way */ bool add(colib::bytearray &image) { // check if new subimage is not wider than remaining space in current // line (width + one for start marker + one for end marker) if(x+image.dim(0)+2 > data.dim(0)) { // check if image would fit at all (-2 for start and end marker!) if(image.dim(0)>data.dim(0)-2) throw "image too wide"; // go to next line and insert it there new_line(); } // check if new image is higher than hmax if (image.dim(1) > hmax) { hmax = image.dim(1); // make sure that new image height does not exceed total height if(y+hmax > data.dim(1)) return false; // adjust line height marker in very first column for(int i=0;i 0); ASSERT(y > 0); data(x-1,y-1) = 0; x += image.dim(0); // insert end marker ASSERT(y > 0); data(x,y-1) = 0; // maybe we don't need ncomp... ncomp++; return true; } /** * store grid in a FILE stream */ void save(FILE *stream,bool crop=true) { if(crop) { colib::bytearray tmp; int width=-1, height=-1; // strip superfluous whitespace from the right bool leave = false; for(int i=data.dim(0)-1;i>=0 && !leave;i--) { for(int j=0;j=0; j--) { if(data(0,j)==0) { height=j+1; break; } } tmp.resize(width,height); for(int i=0;i 0) { int xBak = x, yBak = y; reset(); colib::bytearray lineinfo; next(lineinfo); if (lineinfo.dim(0) == 1) { int numBlack = 0; // go up the 'bar' and count exactly 4 black pixels for (int i = 0; i < lineinfo.dim(1); ++i) { if (lineinfo(0, i) == 0) { ++numBlack; } } if (numBlack == 4) retval = true; } x = xBak; y = yBak; } return retval; } bool next(colib::bytearray &image) { image.resize(0,0); int xorig=x; int yorig=y; int x1,y1; for(;;) { y1 = y; while(y1=0; j--) { if(data(0,j)==0) { num++; if(num==2) { y=j; break; } } } if(num<2) { reset(); return 0; } // now search for position in row. for(int i=1;i