void xoImageTester::CreateOrVerifyTruthImage(bool create, const char* filename, std::function<void(xo::DomNode& root)> setup) { // populate the document Wnd->DocGroup->Doc->Reset(); setup(Wnd->DocGroup->Doc->Root); // if filename is not rooted, then assume it's relative to 'testdata' xo::String fixedRoot = filename; if (filename[0] != '/' && filename[0] != '\\' && filename[1] != ':') fixedRoot = PathRelativeToTestData(filename); xo::String truthFile = fixedRoot; xo::String newSample = fixedRoot + "-observed-result"; truthFile += ".png"; newSample += ".png"; xo::Image img; xo::RenderResult res = Wnd->DocGroup->RenderToImage(img); if (create) { stbi_write_png(truthFile.Z, img.GetWidth(), img.GetHeight(), 4, img.TexDataAtLine(0), img.TexStride); } else { int width = 0, height = 0, comp = 0; unsigned char* data = stbi_load(truthFile.Z, &width, &height, &comp, 4); bool same = ImageEquals(img.GetWidth(), img.GetHeight(), img.TexStride, img.TexDataAtLine(0), width, height, width * 4, data); if (!same) { stbi_write_png(newSample.Z, img.GetWidth(), img.GetHeight(), 4, img.TexDataAtLine(0), img.TexStride); } TTASSERT(same); stbi_image_free(data); } }
void AppendProperty(const ACE_TString& prop, const AudioCodec& codec, ACE_TString& dest_str) { intvec_t codec_prop; switch(codec.codec) { case CODEC_NO_CODEC : codec_prop.push_back(codec.codec); break; case CODEC_SPEEX : /* do not change the order since it will break compatibility * with older clients */ codec_prop.push_back(codec.codec); codec_prop.push_back(codec.speex.bandmode); codec_prop.push_back(codec.speex.quality); codec_prop.push_back(codec.speex.frames_per_packet); codec_prop.push_back(codec.speex.sim_stereo); break; case CODEC_SPEEX_VBR : /* do not change the order since it will break compatibility * with older clients */ codec_prop.push_back(codec.codec); codec_prop.push_back(codec.speex_vbr.bandmode); codec_prop.push_back(codec.speex_vbr.vbr_quality); codec_prop.push_back(codec.speex_vbr.bitrate); codec_prop.push_back(codec.speex_vbr.max_bitrate); codec_prop.push_back(codec.speex_vbr.dtx); codec_prop.push_back(codec.speex_vbr.frames_per_packet); codec_prop.push_back(codec.speex_vbr.sim_stereo); break; case CODEC_OPUS : codec_prop.push_back(codec.codec); codec_prop.push_back(codec.opus.samplerate); codec_prop.push_back(codec.opus.channels); codec_prop.push_back(codec.opus.application); codec_prop.push_back(codec.opus.complexity); codec_prop.push_back(codec.opus.fec); codec_prop.push_back(codec.opus.dtx); codec_prop.push_back(codec.opus.bitrate); codec_prop.push_back(codec.opus.vbr); codec_prop.push_back(codec.opus.vbr_constraint); codec_prop.push_back(codec.opus.frame_size); break; default : codec_prop.push_back(CODEC_NO_CODEC); TTASSERT(codec.codec != CODEC_NO_CODEC); } AppendProperty(prop, codec_prop, dest_str); }
int ExtractProperties(const ACE_TString& input, mstrings_t& properties) { TTASSERT(input.find('\n') == input.rfind('\n')); bool bSyntaxError = false; if( input.length() == 0 ) bSyntaxError = true; size_t offset = input.find(' ');//past command if(offset == ACE_TString::npos) return 0; while(offset < input.length() && !bSyntaxError) { //past any spaces offset = pastBlanks(offset, input); if(offset == input.length()) { break; } size_t propBegin = offset; ACE_TString prop; ACE_TString value; while(offset < input.length()) //extract property name { if( input[offset] != ' ' && input[offset] != '=') offset ++; else break; } if(offset == input.length()) { bSyntaxError = true; //no properties in ACE_TString break; } prop = input.substr(propBegin, offset-propBegin); //set propertyname TTASSERT(properties.find(prop) == properties.end()); offset = pastBlanks(offset, input); //past spaces if(offset == input.length()) { bSyntaxError = true; break; } if(input[offset] != '=') { bSyntaxError = true; break; } else offset ++; //past = offset = pastBlanks(offset, input); //past spaces if(offset == input.length()) { bSyntaxError = true; break; } //determine whether it's a string or an integer if(input[offset] == '"') //a ACE_TString { bool found = false; size_t strBegin = ++offset; //past " while(!found && offset<input.length()) { /* if(input[offset]==ACE_TEXT('\"') && input[offset-1] != ACE_TEXT('\\')) found = true; offset++; */ if(input[offset] == '\\') offset += 2; else if(input[offset] == '"') { found = true; offset++; } else offset++; } if(!found) { bSyntaxError = true; break; } value = input.substr(strBegin, offset-strBegin-1); offset ++; //past \" properties[prop] = RebuildString(value); //properties.SetAt(prop, RebuildString(value)); } else if(input[offset] == '[') // an int list { bool found = false; size_t listBegin = ++offset; //past " while(!found && offset<input.length()) { if(input[offset] == ']') found = true; offset++; } if(!found) { bSyntaxError = true; break; } value = input.substr(listBegin, offset-listBegin-1); offset ++; //past ] properties[prop] = RebuildString(value); //properties.SetAt(prop, RebuildString(value)); } else //eat what's left until space { size_t intBegin = offset; while(offset<input.length() && input[offset] != ' ' && input[offset] != '\r' && input[offset] != '\n') offset ++; //past spaces value = input.substr(intBegin, offset-intBegin); properties[prop] = RebuildString(value); //properties.SetAt(prop, RebuildString(value)); } } return bSyntaxError? -1 : (int)properties.size(); }