Parses the given box file string into a page_number, utf8_str, and bounding_box. Returns true on a successful parse. The box file is assumed to contain box definitions, one per line, of the following format for blob-level boxes: and for word/line-level boxes: WordStr # See applyybox
| 164 | // WordStr <left> <bottom> <right> <top> <page id> #<space-delimited word str> |
| 165 | // See applyybox.cpp for more information. |
| 166 | bool ParseBoxFileStr(const char* boxfile_str, int* page_number, |
| 167 | STRING* utf8_str, TBOX* bounding_box) { |
| 168 | *bounding_box = TBOX(); // Initialize it to empty. |
| 169 | *utf8_str = ""; |
| 170 | char uch[kBoxReadBufSize]; |
| 171 | const char *buffptr = boxfile_str; |
| 172 | // Read the unichar without messing up on Tibetan. |
| 173 | // According to issue 253 the utf-8 surrogates 85 and A0 are treated |
| 174 | // as whitespace by sscanf, so it is more reliable to just find |
| 175 | // ascii space and tab. |
| 176 | int uch_len = 0; |
| 177 | // Skip unicode file designation, if present. |
| 178 | const unsigned char *ubuf = reinterpret_cast<const unsigned char*>(buffptr); |
| 179 | if (ubuf[0] == 0xef && ubuf[1] == 0xbb && ubuf[2] == 0xbf) |
| 180 | buffptr += 3; |
| 181 | // Allow a single blank as the UTF-8 string. Check for empty string and |
| 182 | // then blindly eat the first character. |
| 183 | if (*buffptr == '\0') return false; |
| 184 | do { |
| 185 | uch[uch_len++] = *buffptr++; |
| 186 | } while (*buffptr != '\0' && *buffptr != ' ' && *buffptr != '\t' && |
| 187 | uch_len < kBoxReadBufSize - 1); |
| 188 | uch[uch_len] = '\0'; |
| 189 | if (*buffptr != '\0') ++buffptr; |
| 190 | int x_min, y_min, x_max, y_max; |
| 191 | *page_number = 0; |
| 192 | int count = sscanf(buffptr, "%d %d %d %d %d", |
| 193 | &x_min, &y_min, &x_max, &y_max, page_number); |
| 194 | if (count != 5 && count != 4) { |
| 195 | tprintf("Bad box coordinates in boxfile string! %s\n", ubuf); |
| 196 | return false; |
| 197 | } |
| 198 | // Test for long space-delimited string label. |
| 199 | if (strcmp(uch, kMultiBlobLabelCode) == 0 && |
| 200 | (buffptr = strchr(buffptr, '#')) != NULL) { |
| 201 | strncpy(uch, buffptr + 1, kBoxReadBufSize - 1); |
| 202 | uch[kBoxReadBufSize - 1] = '\0'; // Prevent buffer overrun. |
| 203 | chomp_string(uch); |
| 204 | uch_len = strlen(uch); |
| 205 | } |
| 206 | // Validate UTF8 by making unichars with it. |
| 207 | int used = 0; |
| 208 | while (used < uch_len) { |
| 209 | UNICHAR ch(uch + used, uch_len - used); |
| 210 | int new_used = ch.utf8_len(); |
| 211 | if (new_used == 0) { |
| 212 | tprintf("Bad UTF-8 str %s starts with 0x%02x at col %d\n", |
| 213 | uch + used, uch[used], used + 1); |
| 214 | return false; |
| 215 | } |
| 216 | used += new_used; |
| 217 | } |
| 218 | *utf8_str = uch; |
| 219 | if (x_min > x_max) Swap(&x_min, &x_max); |
| 220 | if (y_min > y_max) Swap(&y_min, &y_max); |
| 221 | bounding_box->set_to_given_coords(x_min, y_min, x_max, y_max); |
| 222 | return true; // Successfully read a box. |
| 223 | } |
no test coverage detected