void Buffer_deinit (Buffer* buffer) { deFree(buffer->data); Buffer_init(buffer); }
/*--------------------------------------------------------------------*//*! * \brief Write base64 encoded raw image data into log * \param log qpTestLog instance * \param name Unique name (matching names can be compared across BatchResults). * \param description Textual description (shown in Candy). * \param compressionMode Compression mode * \param imageFormat Color format * \param width Width in pixels * \param height Height in pixels * \param stride Data stride (offset between rows) * \param data Pointer to pixel data * \return 0 if OK, otherwise <0 *//*--------------------------------------------------------------------*/ deBool qpTestLog_writeImage ( qpTestLog* log, const char* name, const char* description, qpImageCompressionMode compressionMode, qpImageFormat imageFormat, int width, int height, int stride, const void* data) { char widthStr[32]; char heightStr[32]; qpXmlAttribute attribs[8]; int numAttribs = 0; Buffer compressedBuffer; const void* writeDataPtr = DE_NULL; size_t writeDataBytes = ~(size_t)0; DE_ASSERT(log && name); DE_ASSERT(deInRange32(width, 1, 32768)); DE_ASSERT(deInRange32(height, 1, 32768)); DE_ASSERT(data); if (log->flags & QP_TEST_LOG_EXCLUDE_IMAGES) return DE_TRUE; /* Image not logged. */ Buffer_init(&compressedBuffer); /* BEST compression mode defaults to PNG. */ if (compressionMode == QP_IMAGE_COMPRESSION_MODE_BEST) { #if defined(QP_SUPPORT_PNG) compressionMode = QP_IMAGE_COMPRESSION_MODE_PNG; #else compressionMode = QP_IMAGE_COMPRESSION_MODE_NONE; #endif } #if defined(QP_SUPPORT_PNG) /* Try storing with PNG compression. */ if (compressionMode == QP_IMAGE_COMPRESSION_MODE_PNG) { deBool compressOk = compressImagePNG(&compressedBuffer, imageFormat, width, height, stride, data); if (compressOk) { writeDataPtr = compressedBuffer.data; writeDataBytes = compressedBuffer.size; } else { /* Fall-back to default compression. */ qpPrintf("WARNING: PNG compression failed -- storing image uncompressed.\n"); compressionMode = QP_IMAGE_COMPRESSION_MODE_NONE; } } #endif /* Handle image compression. */ switch (compressionMode) { case QP_IMAGE_COMPRESSION_MODE_NONE: { int pixelSize = imageFormat == QP_IMAGE_FORMAT_RGB888 ? 3 : 4; int packedStride = pixelSize*width; if (packedStride == stride) writeDataPtr = data; else { /* Need to re-pack pixels. */ if (Buffer_resize(&compressedBuffer, (size_t)(packedStride*height))) { int row; for (row = 0; row < height; row++) memcpy(&compressedBuffer.data[packedStride*row], &((const deUint8*)data)[row*stride], (size_t)(pixelSize*width)); } else { qpPrintf("ERROR: Failed to pack pixels for writing.\n"); Buffer_deinit(&compressedBuffer); return DE_FALSE; } } writeDataBytes = (size_t)(packedStride*height); break; } #if defined(QP_SUPPORT_PNG) case QP_IMAGE_COMPRESSION_MODE_PNG: DE_ASSERT(writeDataPtr); /* Already handled. */ break; #endif default: qpPrintf("qpTestLog_writeImage(): Unknown compression mode: %s\n", QP_LOOKUP_STRING(s_qpImageCompressionModeMap, compressionMode)); Buffer_deinit(&compressedBuffer); return DE_FALSE; } /* Fill in attributes. */ int32ToString(width, widthStr); int32ToString(height, heightStr); attribs[numAttribs++] = qpSetStringAttrib("Name", name); attribs[numAttribs++] = qpSetStringAttrib("Width", widthStr); attribs[numAttribs++] = qpSetStringAttrib("Height", heightStr); attribs[numAttribs++] = qpSetStringAttrib("Format", QP_LOOKUP_STRING(s_qpImageFormatMap, imageFormat)); attribs[numAttribs++] = qpSetStringAttrib("CompressionMode", QP_LOOKUP_STRING(s_qpImageCompressionModeMap, compressionMode)); if (description) attribs[numAttribs++] = qpSetStringAttrib("Description", description); /* \note Log lock is acquired after compression! */ deMutex_lock(log->lock); /* <Image ID="result" Name="Foobar" Width="640" Height="480" Format="RGB888" CompressionMode="None">base64 data</Image> */ if (!qpXmlWriter_startElement(log->writer, "Image", numAttribs, attribs) || !qpXmlWriter_writeBase64(log->writer, (const deUint8*)writeDataPtr, writeDataBytes) || !qpXmlWriter_endElement(log->writer, "Image")) { qpPrintf("qpTestLog_writeImage(): Writing XML failed\n"); deMutex_unlock(log->lock); Buffer_deinit(&compressedBuffer); return DE_FALSE; } deMutex_unlock(log->lock); /* Free compressed data if allocated. */ Buffer_deinit(&compressedBuffer); return DE_TRUE; }
uint8_t acp::compress(wstring filename, cmder set, ProgressInfo &pinfo) { uint8_t *ftDATA = new uint8_t[2048000]; uint64_t p_ftDATA = 0; //try open file bitWfile fout; FILE *inf = _wfopen(filename.c_str(), L"rb"); if (inf == NULL) return 0x1; fseek(inf, 0, SEEK_END); pinfo.inlen = ftell(inf); fseek(inf, 0, SEEK_SET); fread(ftDATA, 1, pinfo.inlen, inf); fseek(inf, 0, SEEK_SET); wstring ofilename = filename + L".amc"; if (!fout.open(ofilename)) return 0x2; #if DEBUG //wchar_t db_str[120]; db_log(true); #endif //Head Part FHeader fhead; fhead.diccount = set.dictcount; fhead.bufcount = set.bufcount; fhead.toData(); fout.putChars(20, fhead.data);//write file head uint8_t fnl = (uint8_t)filename.size(); fout.putChars(1, &fnl);//file name length fout.putChars(fnl * 2, (uint8_t*)filename.c_str());//file name data fout.putChars(8, (uint8_t*)&pinfo.inlen);//input file length pinfo.outnow = fout.getpos(); //start Dict_init(set.dictcount); Buffer_init(set.bufcount); uint8_t next_read = 64; ChkItem chkdata; DictOP dOP; BufferOP bOP; CoderOP cOP; DictReport *dRep = new DictReport[set.thread]; BufferReport *bRep = new BufferReport[set.thread]; unique_lock <mutex> lck_DictUse(mtx_Dict_Use); thread T_FD = thread(FindInDict, set.thread, ref(dOP), dRep, ref(chkdata)); dOP.op = 1; T_FD.detach(); //give up lck to enable FindInDict to init cv_Dict_Ready.wait(lck_DictUse, [&] {return dOP.op == 0; }); unique_lock <mutex> lck_BufUse(mtx_Buf_Use); thread T_FB = thread(FindInBuffer, set.thread, ref(bOP), bRep, ref(chkdata)); bOP.op = 1; T_FB.detach(); //give up lck to enable FindInBuffer to init cv_Buf_Ready.wait(lck_BufUse, [&] {return bOP.op == 0; }); /* unique_lock <mutex> lck_CoderUse(mtx_Coder_Use); thread T_C = thread(CoderT, ref(fout), ref(cOP)); cOP.op = 1; T_C.detach(); //give up lck to enable Coder to init cv_Coder_Ready.wait(lck_CoderUse, [&] {return cOP.op == 0; }); */ uint32_t d_cycle = 0; dOP.op = bOP.op = 1; CodeAns Dans, Bans; #if DEBUG auto chkadddata = [&] { for (auto a = 0; a < bOP.len; ++a) { if (ftDATA[p_ftDATA++] != bOP.data[a]) return false; } return true; }; #endif while (Chk_upd(chkdata, inf, next_read) >= 3)//loop untill file end { // swprintf(db_str, L"**Main loop %d .\n",++z_cycle); db_log(db_str); Chk_pre(chkdata, 3); #if DEBUG if (bOP.op == 0xfe) { if (dOP.op == 0xfd) { d_cycle++; //if (d_cycle == 6) //printf("reach\n"); } if (!chkadddata()) { //wprintf(L"\nwrong add data!at %d dict-cycle\n",d_cycle); } } #endif //Dict Part cv_Dict_Use.notify_all(); #if DEBUG_Thr db_log(L"M** noti DC0\n"); #endif cv_Dict_Ready.wait(lck_DictUse, [&] {return dOP.op == 0x7f; }); #if DEBUG_Thr db_log(L"M** wa<- DC0\n"); #endif //pre Dict Ans future<CodeAns> GetDictTestAns = async(Code_TestDict,set.thread,dRep); #if DEBUG_Thr db_log(L"M** make CTD\n"); #endif //prepare data for buffer if (dOP.findlen > 3) Chk_pre(chkdata, dOP.findlen); //Buffer Part cv_Buf_Use.notify_all(); #if DEBUG_Thr db_log(L"M** noti BC0\n"); #endif cv_Buf_Ready.wait(lck_BufUse, [&] {return bOP.op == 0x7f; }); #if DEBUG_Thr db_log(L"M** wa<- BC0\n"); #endif //pre Buf Ans future<CodeAns> GetBufTestAns = async(Code_TestBuffer, set.thread, bRep); #if DEBUG_Thr db_log(L"M** make CTB\n"); #endif //get Ans Dans = GetDictTestAns.get(); #if DEBUG_Thr db_log(L"M** get CTD\n"); #endif bOP.op = 0xfe; Bans = GetBufTestAns.get(); #if DEBUG_Thr db_log(L"M** get CTB\n"); #endif #if DEBUG_Thr db_log(L"**Get Ans\n"); #endif //pre next op //#if DEBUG { swprintf(db_str, L"@Main ANS dans=%d bans=%d\n", Dans.len, Bans.len); db_log(1, db_str, true); } if(Bans.savelen >= Dans.savelen)//Buffer find more&equal byte OR Buffer save more&equal space {// //if (Bans.savelen == (int16_t)0x8000)//both unavaliable if (Bans.savelen < 0)//no saving bits { //put one byte and add buffer cOP.bdata = chkdata.data[0]; bOP.len = next_read = 1; bOP.data[0] = cOP.bdata; cOP.op = 0xfe; dOP.op = 0x33; } else { //put buffer and add dict and buffer cOP.cdata = Bans; dOP.op = 0xfe; bOP.len = dOP.len = next_read = Bans.srclen; memcpy(bOP.data, chkdata.data, next_read); memcpy(dOP.data, chkdata.data, next_read); //bOP.data = dOP.data = Bans.addr; cOP.op = 0xfd; dOP.bOffset = Bans.part_data[5]; dOP.p_b = Bans.p_b; dOP.s_b = Bans.s_b; } } else { //put dict and use dict and add buffer cOP.cdata = Dans; dOP.op = 0xfd; //bOP.data = Dans.addr; dOP.len = bOP.len = next_read = Dans.srclen; memcpy(bOP.data, Dans.addr, next_read); dOP.dID = Dans.dID; cOP.op = 0xfd; } //send data to coder /* cv_Coder_Use.notify_all(); cv_Coder_Ready.wait(lck_CoderUse, [&] {return cOP.op == 0x0; });//give up lock so that coder can do work */ Coder(fout, cOP); //refresh progress-info pinfo.innow += next_read; pinfo.outnow = fout.pos(); } if (chkdata.limit)//still little data { cOP.enddata[0] = chkdata.limit; pinfo.innow += chkdata.limit; cOP.enddata[1] = chkdata.data[0]; cOP.enddata[2] = chkdata.data[1]; } //end bOP.op = cOP.op = dOP.op = 0xff; //end dict cv_Dict_Use.notify_all(); cv_Dict_Ready.wait(lck_DictUse, [&] {return dOP.op == 0x7f; }); //end buffer cv_Buf_Use.notify_all(); cv_Buf_Ready.wait(lck_BufUse, [&] {return bOP.op == 0x7f; }); //end coder /* cv_Coder_Use.notify_all(); cv_Coder_Ready.wait(lck_CoderUse, [&] {return cOP.op == 0x7f; });//give up lock so that coder can do work */ Coder(fout, cOP); Dict_exit(); Buffer_exit(); pinfo.outlen = fout.close(); fclose(inf); #if DEBUG db_log(); #endif return 0x0; }