//------------------------------------------------------------------------------------------------------------------ bool FormatSgi::SaveImage (const char* acFilename) { char cZero = 0; Stream qSaveStream(acFilename,false); // Header. short sSignature = 474; qSaveStream.Write(sSignature); char cStorage; switch ( m_eCompression ) { case CT_NONE: cStorage = 0; break; case CT_RLE: cStorage = 1; break; } qSaveStream.Write(cStorage); char cBytesPerChannel = m_iBytesPerSample; qSaveStream.Write(cBytesPerChannel); unsigned short usNumberOfDimensions; switch ( m_eColorModel ) { case CMT_GRAYSCALE: usNumberOfDimensions = 2; break; case CMT_GRAYSCALE_WITH_ALPHA: case CMT_RGB: case CMT_RGBA: usNumberOfDimensions = 3; break; } qSaveStream.Write(usNumberOfDimensions); unsigned short usSizeX = m_iWidth; unsigned short usSizeY = m_iHeight; unsigned short usSizeZ = m_iSampleQuantity; qSaveStream.Write(usSizeX); qSaveStream.Write(usSizeY); qSaveStream.Write(usSizeZ); int iMinPixVal = 0; int iMaxPixVal = (1 << m_iBytesPerSample*8) - 1; qSaveStream.Write(iMinPixVal); qSaveStream.Write(iMaxPixVal); for (int i = 0; i < 84; i++) qSaveStream.Write(cZero); int iColormapId = 0; qSaveStream.Write(iColormapId); for (int i = 0; i < 404; i++) qSaveStream.Write(cZero); int iScanlineQuantity = m_iSampleQuantity*m_iHeight; if ( m_eCompression == CT_RLE ) { // will overwrite SGI scanline offsets and lengths later int iTablesDataSize = iScanlineQuantity*8; for (int i = 0; i < iTablesDataSize; i++) qSaveStream.Write(cZero); } // for a progress bar ProgressProbe qProgress(this); qProgress.SetAdvance(1.0f/iScanlineQuantity); // write the image int iScanlineByteSize = m_iWidth*m_iBytesPerSample; StillArray<unsigned char> qUncompressedScanline(iScanlineByteSize); int iHMO = m_iHeight - 1; unsigned char* pucSample; unsigned short usValue; unsigned char ucSample0, ucSample1, ucPrevSample; unsigned short usSample0, usSample1, usPrevSample; bool bLastRunWasLiteral; int iSamplesLeft, iRunLength, iLastLiteralRunLength, iLastLiteralCounterPos, iCodedSampleQuantity; int iLengthsTablePos, iSLRecCount, iInTabOff, iOffset, iByteLength; if ( m_eCompression == CT_RLE ) { iLengthsTablePos = 512 + iScanlineQuantity*4; iSLRecCount = 0; } float afSamples[4]; for (int i0 = 0; i0 < m_iSampleQuantity; i0++) { for (int iY = iHMO; iY >= 0; iY--) { // assign sample values pucSample = qUncompressedScanline; for (int iX = 0; iX < m_iWidth; iX++) { if ( m_eColorModel == CMT_GRAYSCALE ) { afSamples[0] = m_spqImageSaveTo->GetPixelIntensity(iX,iY); } else if ( m_eColorModel == CMT_GRAYSCALE_WITH_ALPHA ) { Link<float,float> qIntensityWithAlpha = m_spqImageSaveTo->GetPixelIntensityWithAlpha(iX,iY); afSamples[0] = qIntensityWithAlpha.First; afSamples[1] = qIntensityWithAlpha.Second; } else if ( m_eColorModel == CMT_RGB ) { ColorRgb qColorRgb = m_spqImageSaveTo->GetPixelRgb(iX,iY); for (int i1 = 0; i1 < 3; i1++) afSamples[i1] = qColorRgb[i1]; } else // m_eColorModel = CMT_RGBA { ColorRgba qColorRgba = m_spqImageSaveTo->GetPixelRgba(iX,iY); for (int i1 = 0; i1 < 4; i1++) afSamples[i1] = qColorRgba[i1]; } if ( m_iBytesPerSample == 1 ) { *pucSample++ = Mathf::RoundToInt(afSamples[i0]*255); } else // m_iBytesPerSample = 2 { usValue = Mathf::RoundToInt(afSamples[i0]*65535); Storage::Write2be((char*)pucSample,1,&usValue); pucSample += 2; } } if ( m_eCompression == CT_NONE ) { qSaveStream.Write(iScanlineByteSize,qUncompressedScanline); } else { // pack the scanline bLastRunWasLiteral = false; iCodedSampleQuantity = 0; if ( m_iBytesPerSample == 1 ) { Array<unsigned char> qCompressedScanline; for (/**/; /**/; /**/) { iSamplesLeft = m_iWidth - iCodedSampleQuantity; if ( iSamplesLeft == 0 ) break; if ( iSamplesLeft == 1 ) { if ( bLastRunWasLiteral && iLastLiteralRunLength < 127 ) qCompressedScanline[iLastLiteralCounterPos]++; else qCompressedScanline.Push(129); qCompressedScanline.Push(qUncompressedScanline[iCodedSampleQuantity]); break; } ucSample0 = qUncompressedScanline[iCodedSampleQuantity+0]; ucSample1 = qUncompressedScanline[iCodedSampleQuantity+1]; iRunLength = 2; if ( ucSample0 != ucSample1 ) { ucPrevSample = ucSample1; for (int i1 = iCodedSampleQuantity+2; i1 < m_iWidth; i1++) { if ( qUncompressedScanline[i1] == ucPrevSample ) { iRunLength--; break; } if ( ++iRunLength == 127 ) break; ucPrevSample = qUncompressedScanline[i1]; } if ( bLastRunWasLiteral && iLastLiteralRunLength + iRunLength <= 127 ) { qCompressedScanline[iLastLiteralCounterPos] += iRunLength; for (int i1 = 0; i1 < iRunLength; i1++) qCompressedScanline.Push(qUncompressedScanline[iCodedSampleQuantity++]); iLastLiteralRunLength += iRunLength; } else { iLastLiteralCounterPos = qCompressedScanline.GetQuantity(); qCompressedScanline.Push(128 | iRunLength); for (int i1 = 0; i1 < iRunLength; i1++) qCompressedScanline.Push(qUncompressedScanline[iCodedSampleQuantity++]); iLastLiteralRunLength = iRunLength; bLastRunWasLiteral = true; } } else { for (int i1 = iCodedSampleQuantity+2; i1 < m_iWidth; i1++) { if ( qUncompressedScanline[i1] != ucSample0 ) break; if ( ++iRunLength == 127 ) break; } if ( iRunLength == 2 && bLastRunWasLiteral && iLastLiteralRunLength + 2 <= 127 ) { qCompressedScanline[iLastLiteralCounterPos] += 2; for (int i1 = 0; i1 < 2; i1++) qCompressedScanline.Push(ucSample0); iLastLiteralRunLength += 2; iCodedSampleQuantity += 2; } else { qCompressedScanline.Push(iRunLength); qCompressedScanline.Push(ucSample0); iCodedSampleQuantity += iRunLength; bLastRunWasLiteral = false; } } } qCompressedScanline.Push(0); iOffset = qSaveStream.GetBytePosition(); qSaveStream.PushPositionState(); iInTabOff = iSLRecCount*4; qSaveStream.SetBytePosition(512+iInTabOff); qSaveStream.Write(iOffset); iByteLength = qCompressedScanline.GetQuantity(); qSaveStream.SetBytePosition(iLengthsTablePos+iInTabOff); qSaveStream.Write(iByteLength); qSaveStream.PopPositionState(); qSaveStream.Write(qCompressedScanline.GetQuantity(),qCompressedScanline); } else // m_iBytesPerSample = 2 { Array<unsigned short> qCompressedScanline; for (/**/; /**/; /**/) { iSamplesLeft = m_iWidth - iCodedSampleQuantity; if ( iSamplesLeft == 0 ) break; if ( iSamplesLeft == 1 ) { if ( bLastRunWasLiteral && iLastLiteralRunLength < 127 ) qCompressedScanline[iLastLiteralCounterPos]++; else qCompressedScanline.Push(129); qCompressedScanline.Push( ExtractUShortValue(qUncompressedScanline,iCodedSampleQuantity)); break; } usSample0 = ExtractUShortValue(qUncompressedScanline,iCodedSampleQuantity+0); usSample1 = ExtractUShortValue(qUncompressedScanline,iCodedSampleQuantity+1); iRunLength = 2; if ( usSample0 != usSample1 ) { usPrevSample = usSample1; for (int i1 = iCodedSampleQuantity+2; i1 < m_iWidth; i1++) { if ( ExtractUShortValue(qUncompressedScanline,i1) == usPrevSample ) { iRunLength--; break; } if ( ++iRunLength == 127 ) break; usPrevSample = ExtractUShortValue(qUncompressedScanline,i1); } if ( bLastRunWasLiteral && iLastLiteralRunLength + iRunLength <= 127 ) { qCompressedScanline[iLastLiteralCounterPos] += iRunLength; for (int i1 = 0; i1 < iRunLength; i1++) { qCompressedScanline.Push( ExtractUShortValue(qUncompressedScanline,iCodedSampleQuantity++)); } iLastLiteralRunLength += iRunLength; } else { iLastLiteralCounterPos = qCompressedScanline.GetQuantity(); qCompressedScanline.Push(128 | iRunLength); for (int i1 = 0; i1 < iRunLength; i1++) { qCompressedScanline.Push( ExtractUShortValue(qUncompressedScanline,iCodedSampleQuantity++)); } iLastLiteralRunLength = iRunLength; bLastRunWasLiteral = true; } } else { for (int i1 = iCodedSampleQuantity+2; i1 < m_iWidth; i1++) { if ( ExtractUShortValue(qUncompressedScanline,i1) != usSample0 ) break; if ( ++iRunLength == 127 ) break; } if ( iRunLength == 2 && bLastRunWasLiteral && iLastLiteralRunLength + 2 <= 127 ) { qCompressedScanline[iLastLiteralCounterPos] += 2; for (int i1 = 0; i1 < 2; i1++) qCompressedScanline.Push(usSample0); iLastLiteralRunLength += 2; iCodedSampleQuantity += 2; } else { qCompressedScanline.Push(iRunLength); qCompressedScanline.Push(usSample0); iCodedSampleQuantity += iRunLength; bLastRunWasLiteral = false; } } } qCompressedScanline.Push(0); iOffset = qSaveStream.GetBytePosition(); qSaveStream.PushPositionState(); iInTabOff = iSLRecCount*4; qSaveStream.SetBytePosition(512+iInTabOff); qSaveStream.Write(iOffset); iByteLength = qCompressedScanline.GetQuantity()*2; qSaveStream.SetBytePosition(iLengthsTablePos+iInTabOff); qSaveStream.Write(iByteLength); qSaveStream.PopPositionState(); qSaveStream.Write(qCompressedScanline.GetQuantity(),qCompressedScanline); } iSLRecCount++; } qProgress.MakeAdvance(); } } qUncompressedScanline.RemoveAll(); // flush to the file CONDITIONAL_THROW_EXCEPTION(qSaveStream.Finalize(),ET_CANNOT_ACCESS_FILE); return true; }
int main() { STUDENT student, student1, student2; STUDENT* students = new STUDENT[3]; const char cFirstName[LEN_NAME] = "Vasya "; const char cFirstName1[LEN_NAME] = "Petya "; const char cFirstName2[LEN_NAME]= "Leshaa "; strcpy (student.FirstName, cFirstName); strcpy (student1.FirstName, cFirstName1); strcpy (student2.FirstName, cFirstName2); students[0] = student; students[1] = student1; students[2] = student2; Array a (students, 3); //delete[] students; //size_t nQnt = a.GetQuantity(); //students = new STUDENT[nQnt]; //students = a.GetStudents(); for (size_t i = 0 ; i < 3; i++){ cout << students[i].FirstName<< endl; } for (size_t i = 0; i <5 ; i++){ cout << "ADD#"<< i <<".0"<<endl; a.Add (students[0]); cout << "ADD#"<< i <<".1"<<endl; a.Add (students[0]); cout << "ADD#"<< i <<".2"<<endl; a.Add (students[0]); } delete[] students; STUDENT** rStud = a.GetStudents(); size_t nQnt = a.GetQuantity(); cout << "Quantity is "<< nQnt<<endl; for (size_t i = 0 ; i < nQnt; i++){ cout << i << ". "<< rStud[i]->FirstName<< endl; } STUDENT editStudent; const char cFirstNameEdit[LEN_NAME]= "Edit "; strcpy (editStudent.FirstName, cFirstNameEdit); a.Edit (editStudent, 16); cout<<"MAIN EDIT "<<endl; a.Show (); bool* arr = new bool[a.GetQuantity ()]; a.Find( "Vasya", COL_FIRST_NAME , arr ); cout<<"FIND "<<endl; for (size_t i = 0; i < a.GetQuantity (); i++){ cout << i<<". "<< (bool)arr[i]<<endl; } delete[] arr; a.DeleteStudent (14); cout<<"DELETE "<<endl; //a.Show (); cout << "Hello World!" << endl; return 0; }