virtual int do_length( std::mbstate_t &state, char const *from, char const *from_end, size_t max) const { char const *from_next=from; std::vector<uchar> chrs(max+1); uchar *to=&chrs.front(); uchar *to_end=to+max; uchar *to_next=to; do_in(state,from,from_end,from_next,to,to_end,to_next); return from_next-from; }
static FIBITMAP * DLL_CALLCONV Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { char msg[256]; FIBITMAP *dib = NULL; if (!handle) return NULL; try { char *str; //find the starting brace if( !FindChar(io, handle,'{') ) throw "Could not find starting brace"; //read info string str = ReadString(io, handle); if(!str) throw "Error reading info string"; int width, height, colors, cpp; if( sscanf(str, "%d %d %d %d", &width, &height, &colors, &cpp) != 4 ) { free(str); throw "Improperly formed info string"; } free(str); if (colors > 256) { dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK); } else { dib = FreeImage_Allocate(width, height, 8); } //build a map of color chars to rgb values std::map<std::string,FILE_RGBA> rawpal; //will store index in Alpha if 8bpp for(int i = 0; i < colors; i++ ) { FILE_RGBA rgba; str = ReadString(io, handle); if(!str) throw "Error reading color strings"; std::string chrs(str,cpp); //create a string for the color chars using the first cpp chars char *keys = str + cpp; //the color keys for these chars start after the first cpp chars //translate all the tabs to spaces char *tmp = keys; while( strchr(tmp,'\t') ) { tmp = strchr(tmp,'\t'); *tmp++ = ' '; } //prefer the color visual if( strstr(keys," c ") ) { char *clr = strstr(keys," c ") + 3; while( *clr == ' ' ) clr++; //find the start of the hex rgb value if( *clr == '#' ) { int red = 0, green = 0, blue = 0, n; clr++; //end string at first space, if any found if( strchr(clr,' ') ) *(strchr(clr,' ')) = '\0'; //parse hex color, it can be #rgb #rrggbb #rrrgggbbb or #rrrrggggbbbb switch( strlen(clr) ) { case 3: n = sscanf(clr,"%01x%01x%01x",&red,&green,&blue); red |= (red << 4); green |= (green << 4); blue |= (blue << 4); break; case 6: n = sscanf(clr,"%02x%02x%02x",&red,&green,&blue); break; case 9: n = sscanf(clr,"%03x%03x%03x",&red,&green,&blue); red >>= 4; green >>= 4; blue >>= 4; break; case 12: n = sscanf(clr,"%04x%04x%04x",&red,&green,&blue); red >>= 8; green >>= 8; blue >>= 8; break; default: n = 0; break; } if( n != 3 ) { free(str); throw "Improperly formed hex color value"; } rgba.r = (BYTE)red; rgba.g = (BYTE)green; rgba.b = (BYTE)blue; } else if( !strncmp(clr,"None",4) || !strncmp(clr,"none",4) ) { rgba.r = rgba.g = rgba.b = 0xFF; } else { char *tmp = clr; //scan forward for each space, if its " x " or " xx " end the string there //this means its probably some other visual data beyond that point and not //part of the color name. How many named color end with a 1 or 2 character //word? Probably none in our list at least. while( (tmp = strchr(tmp,' ')) != NULL ) { if( tmp[1] != ' ' ) { if( (tmp[2] == ' ') || (tmp[2] != ' ' && tmp[3] == ' ') ) { tmp[0] = '\0'; break; } } tmp++; } //remove any trailing spaces tmp = clr+strlen(clr)-1; while( *tmp == ' ' ) { *tmp = '\0'; tmp--; } if (!FreeImage_LookupX11Color(clr, &rgba.r, &rgba.g, &rgba.b)) { sprintf(msg, "Unknown color name '%s'", str); free(str); throw msg; } } } else {