//文件解压缩 void UnComparess(const char* filename) { CharInfo arry[256]; //读配置文件 ReadConfig(filename, arry); //重建Haffman树 HuffmanTree<CharInfo> h(arry, 256, CharInfo()); //遍历树,找叶子结点,写输出文件 HuffmanNode<CharInfo>* root = h.GetRootNode(); HuffmanNode<CharInfo>* cur = root; //打开压缩文件读 string Curf(filename); Curf = Curf + ".comparess"; FILE* fread = fopen(Curf.c_str(), "rb"); unsigned char ch = fgetc(fread); FILE* fwrite = fopen("uncompress", "wb"); int readcount = root->_weight._count;//根节点的_count值就是整棵树字符出现的次数//出现次数越多越靠近根节点,编码越短 while (readcount) { int tmp = 1; int bit = 7; //左移的位数 while (bit >= 0) { if (ch & (tmp << bit)) //判断最低位是0还是1 从而决定是left还是right { cur = cur->_right; bit--; } else { cur = cur->_left; bit--; } //找到叶子结点 if (cur->_left == NULL&&cur->_right == NULL) { fputc(cur->_weight._ch, fwrite); cur = root; readcount--; //最后一个字符的编码在最后两个字节当中的情况 if (!readcount) // { break; } } } ch = fgetc(fread); } fclose(fread); fclose(fwrite); }
void TextView::update(const UString& _text, IFont* _font, int _height, Align _align, VertexColourType _format, int _maxheight) { mFontHeight = _height; // массив дл¤ быстрой конвертации цветов static const char convert_colour[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; mViewSize.clear(); RollBackPoint roll_back; IntSize result; int width = 0; size_t count = 0; mLength = 0; mLineInfo.clear(); LineInfo line_info; int font_height = _font->getDefaultHeight(); UString::const_iterator end = _text.end(); UString::const_iterator index = _text.begin(); /*if (index == end) return;*/ result.height += _height; for (; index != end; ++index) { Char character = *index; // нова¤ строка if (character == FontCodeType::CR || character == FontCodeType::NEL || character == FontCodeType::LF) { if (character == FontCodeType::CR) { UString::const_iterator peeki = index; ++peeki; if ((peeki != end) && (*peeki == FontCodeType::LF)) index = peeki; // skip both as one newline } line_info.width = width; line_info.count = count; mLength += line_info.count + 1; result.height += _height; if (result.width < width) result.width = width; width = 0; count = 0; mLineInfo.push_back(line_info); line_info.clear(); // отмен¤ем откат roll_back.clear(); continue; } // тег else if (character == L'#') { // берем следующий символ ++ index; if (index == end) { --index; // это защита continue; } character = *index; // если два подр¤д, то рисуем один шарп, если нет то мен¤ем цвет if (character != L'#') { // парсим первый символ uint32 colour = convert_colour[(character-48) & 0x3F]; // и еще п¤ть символов после шарпа for (char i = 0; i < 5; i++) { ++ index; if (index == end) { --index; // это защита continue; } colour <<= 4; colour += convert_colour[ ((*index) - 48) & 0x3F ]; } // если нужно, то мен¤ем красный и синий компоненты texture_utility::convertColour(colour, _format); line_info.simbols.push_back( CharInfo(colour) ); continue; } } GlyphInfo* info = _font->getGlyphInfo(character); if (FontCodeType::Space == character) { roll_back.set(line_info.simbols.size(), index, count, width); } else if (FontCodeType::Tab == character) { roll_back.set(line_info.simbols.size(), index, count, width); } int char_width = info->width; if (font_height != _height) { char_width = char_width * _height / font_height; if (!char_width) char_width = 1; } // перенос слов if (_maxheight != -1 && (width + char_width) > _maxheight && !roll_back.empty()) { // откатываем до последнего пробела width = roll_back.getLenght(); count = roll_back.getCount(); index = roll_back.getTextIter(); line_info.simbols.erase(line_info.simbols.begin() + roll_back.getPosition(), line_info.simbols.end()); // запоминаем место отката, как полную строку line_info.width = width; line_info.count = count; mLength += line_info.count + 1; result.height += _height; if (result.width < width) result.width = width; width = 0; count = 0; mLineInfo.push_back(line_info); line_info.clear(); // отмен¤ем откат roll_back.clear(); continue; } line_info.simbols.push_back(CharInfo(info->uvRect, char_width)); width += char_width; count ++; } line_info.width = width; line_info.count = count; mLength += line_info.count; mLineInfo.push_back(line_info); if (result.width < width) result.width = width; // теперь выравниванием строки for (VectorLineInfo::iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line) { if (_align.isRight()) line->offset = result.width - line->width; else if (_align.isHCenter()) line->offset = (result.width - line->width) / 2; } mViewSize = result; }
//文件压缩 void Comparess(const char* filename) { FILE* fout = fopen(filename, "rb"); if (fout == NULL) { cout << "打开待压缩文件失败" << endl; return; } for (int i = 0; i < 256; i++) { _info[i]._ch = i; } unsigned char ch = fgetc(fout); //不能使用有符号char,如果,压缩汉字时的字符出现范围是0~255 while (!feof(fout)) //检测流上的文件结束符,判断是否到文件结尾 { //如果文件结束,则返回非0值,否则返回0,文件结束符只能被clearerr()清除 if (ch == '\r') { ch = fgetc(fout); //跳过 if (ch != '\n') { fseek(fout, -1, SEEK_CUR);//遇到‘\r\n’时屏幕上打印换行 //文件内部位置指针 //偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置 } } _info[ch]._count++; //统计出现的次数 ch = fgetc(fout); } HuffmanTree<CharInfo> h(_info, 256, CharInfo()); HuffmanNode<CharInfo>* root = h.GetRootNode(); string str; GenerateHaffmanCode(root, str); //重新打开待压缩文件读 fseek(fout, 0, SEEK_SET); ch = fgetc(fout); unsigned char data = 0; //要写入压缩文件的数据 int bitcount = 7; //标记移位信息 //打开文件写压缩后的编码 string write(filename); write = write + ".comparess"; FILE* fwrite = fopen(write.c_str(), "wb"); while (!feof(fout)) { if (ch == '\r') { ch = fgetc(fout); if (ch != '\n') { fseek(fout, -1, SEEK_CUR); } } const char* cur = _info[ch]._code.c_str(); while (*cur) { if (bitcount >= 0) { data = data | ((*cur - '0') << bitcount); bitcount--; } if (bitcount < 0) { fputc(data, fwrite); bitcount = 7; data = 0; } cur++; } ch = fgetc(fout); } fputc(data, fwrite); //写配置文件 WriteConfig(filename); fclose(fout); fclose(fwrite); }
CharInfo operator+(const CharInfo& c)const { return CharInfo(_count + c._count); }