コード例 #1
0
ファイル: QFormatSgi.cpp プロジェクト: nazariyg/Qcore
//------------------------------------------------------------------------------------------------------------------
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;
}
コード例 #2
0
ファイル: main.cpp プロジェクト: mckey83/BaseArray
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;
}