dgnread.cpp

来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 1,808 行 · 第 1/5 页

CPP
1,808
字号
                      *(psText->string + n) = (char) (w & 0xFF);                       n++; // skip 1 byte;                  }                  else { // if extend code area : 2 byte Korean character                       *(psText->string + n)     = (char) (w >> 8);   // hi                      *(psText->string + n + 1) = (char) (w & 0xFF); // lo                      n+=2; // 2 byte                  }              }              psText->string[n] = '\0'; // terminate C string          }          else          {              memcpy( psText->string, psDGN->abyElem + text_off, num_chars );              psText->string[num_chars] = '\0';          }      }      break;      case DGNT_TCB:        psElement = DGNParseTCB( psDGN );        break;      case DGNT_COMPLEX_CHAIN_HEADER:      case DGNT_COMPLEX_SHAPE_HEADER:      {          DGNElemComplexHeader *psHdr;          psHdr = (DGNElemComplexHeader *)               CPLCalloc(sizeof(DGNElemComplexHeader),1);          psElement = (DGNElemCore *) psHdr;          psElement->stype = DGNST_COMPLEX_HEADER;          DGNParseCore( psDGN, psElement );          psHdr->totlength = psDGN->abyElem[36] + psDGN->abyElem[37] * 256;          psHdr->numelems = psDGN->abyElem[38] + psDGN->abyElem[39] * 256;      }      break;      case DGNT_TAG_VALUE:      {          DGNElemTagValue *psTag;          psTag = (DGNElemTagValue *)               CPLCalloc(sizeof(DGNElemTagValue),1);          psElement = (DGNElemCore *) psTag;          psElement->stype = DGNST_TAG_VALUE;          DGNParseCore( psDGN, psElement );          psTag->tagType = psDGN->abyElem[74] + psDGN->abyElem[75] * 256;          memcpy( &(psTag->tagSet), psDGN->abyElem + 68, 4 );          psTag->tagSet = CPL_LSBWORD32(psTag->tagSet);          psTag->tagIndex = psDGN->abyElem[72] + psDGN->abyElem[73] * 256;          psTag->tagLength = psDGN->abyElem[150] + psDGN->abyElem[151] * 256;          if( psTag->tagType == 1 )          {              psTag->tagValue.string =                   CPLStrdup( (char *) psDGN->abyElem + 154 );          }          else if( psTag->tagType == 3 )          {              memcpy( &(psTag->tagValue.integer),                       psDGN->abyElem + 154, 4 );              psTag->tagValue.integer =                   CPL_LSBWORD32( psTag->tagValue.integer );          }          else if( psTag->tagType == 4 )          {              memcpy( &(psTag->tagValue.real),                       psDGN->abyElem + 154, 8 );              DGN2IEEEDouble( &(psTag->tagValue.real) );          }      }      break;      case DGNT_APPLICATION_ELEM:        if( nLevel == 24 )        {            psElement = DGNParseTagSet( psDGN );        }        else        {            psElement = (DGNElemCore *) CPLCalloc(sizeof(DGNElemCore),1);            psElement->stype = DGNST_CORE;            DGNParseCore( psDGN, psElement );        }        break;      case DGNT_CONE:        {          DGNElemCone *psCone;          psCone = (DGNElemCone *) CPLCalloc(sizeof(DGNElemCone),1);          psElement = (DGNElemCore *) psCone;          psElement->stype = DGNST_CONE;          DGNParseCore( psDGN, psElement );          CPLAssert( psDGN->dimension == 3 );          psCone->unknown = psDGN->abyElem[36] + psDGN->abyElem[37] * 256;          psCone->quat[0] = DGN_INT32( psDGN->abyElem + 38 );          psCone->quat[1] = DGN_INT32( psDGN->abyElem + 42 );          psCone->quat[2] = DGN_INT32( psDGN->abyElem + 46 );          psCone->quat[3] = DGN_INT32( psDGN->abyElem + 50 );           memcpy( &(psCone->center_1.x), psDGN->abyElem + 54, 8 );          DGN2IEEEDouble( &(psCone->center_1.x) );          memcpy( &(psCone->center_1.y), psDGN->abyElem + 62, 8 );          DGN2IEEEDouble( &(psCone->center_1.y) );          memcpy( &(psCone->center_1.z), psDGN->abyElem + 70, 8 );          DGN2IEEEDouble( &(psCone->center_1.z) );          memcpy( &(psCone->radius_1), psDGN->abyElem + 78, 8 );          DGN2IEEEDouble( &(psCone->radius_1) );          memcpy( &(psCone->center_2.x), psDGN->abyElem + 86, 8 );          DGN2IEEEDouble( &(psCone->center_2.x) );          memcpy( &(psCone->center_2.y), psDGN->abyElem + 94, 8 );          DGN2IEEEDouble( &(psCone->center_2.y) );          memcpy( &(psCone->center_2.z), psDGN->abyElem + 102, 8 );          DGN2IEEEDouble( &(psCone->center_2.z) );          memcpy( &(psCone->radius_2), psDGN->abyElem + 110, 8 );          DGN2IEEEDouble( &(psCone->radius_2) );          psCone->radius_1 *= psDGN->scale;          psCone->radius_2 *= psDGN->scale;          DGNTransformPoint( psDGN, &psCone->center_1 );          DGNTransformPoint( psDGN, &psCone->center_2 );        }        break;      case DGNT_3DSURFACE_HEADER:      case DGNT_3DSOLID_HEADER:        {          DGNElemComplexHeader *psShape;          psShape =             (DGNElemComplexHeader *) CPLCalloc(sizeof(DGNElemComplexHeader),1);          psElement = (DGNElemCore *) psShape;          psElement->stype = DGNST_COMPLEX_HEADER;          DGNParseCore( psDGN, psElement );          // Read complex header          psShape->totlength = psDGN->abyElem[36] + psDGN->abyElem[37] * 256;          psShape->numelems = psDGN->abyElem[38] + psDGN->abyElem[39] * 256;          psShape->surftype = psDGN->abyElem[40];          psShape->boundelms = psDGN->abyElem[41] + 1;        }        break;      case DGNT_BSPLINE_SURFACE_HEADER:        {          DGNElemBSplineSurfaceHeader *psSpline;          psSpline = (DGNElemBSplineSurfaceHeader *)            CPLCalloc(sizeof(DGNElemBSplineSurfaceHeader), 1);          psElement = (DGNElemCore *) psSpline;          psElement->stype = DGNST_BSPLINE_SURFACE_HEADER;          DGNParseCore( psDGN, psElement );          // Read B-Spline surface header          psSpline->desc_words = DGN_INT32(psDGN->abyElem + 36);          psSpline->curve_type = psDGN->abyElem[41];          // U          psSpline->u_order = (psDGN->abyElem[40] & 0x0f) + 2;          psSpline->u_properties = psDGN->abyElem[40] & 0xf0;          psSpline->num_poles_u = psDGN->abyElem[42] + psDGN->abyElem[43]*256;          psSpline->num_knots_u = psDGN->abyElem[44] + psDGN->abyElem[45]*256;          psSpline->rule_lines_u = psDGN->abyElem[46] + psDGN->abyElem[47]*256;          // V          psSpline->v_order = (psDGN->abyElem[48] & 0x0f) + 2;          psSpline->v_properties = psDGN->abyElem[48] & 0xf0;          psSpline->num_poles_v = psDGN->abyElem[50] + psDGN->abyElem[51]*256;          psSpline->num_knots_v = psDGN->abyElem[52] + psDGN->abyElem[53]*256;          psSpline->rule_lines_v = psDGN->abyElem[54] + psDGN->abyElem[55]*256;          psSpline->num_bounds = psDGN->abyElem[56] + psDGN->abyElem[57]*556;        }      break;      case DGNT_BSPLINE_CURVE_HEADER:        {          DGNElemBSplineCurveHeader *psSpline;          psSpline = (DGNElemBSplineCurveHeader *)            CPLCalloc(sizeof(DGNElemBSplineCurveHeader), 1);          psElement = (DGNElemCore *) psSpline;          psElement->stype = DGNST_BSPLINE_CURVE_HEADER;          DGNParseCore( psDGN, psElement );          // Read B-Spline curve header          psSpline->desc_words = DGN_INT32(psDGN->abyElem + 36);          // flags          psSpline->order = (psDGN->abyElem[40] & 0x0f) + 2;          psSpline->properties = psDGN->abyElem[40] & 0xf0;          psSpline->curve_type = psDGN->abyElem[41];          psSpline->num_poles = psDGN->abyElem[42] + psDGN->abyElem[43]*256;          psSpline->num_knots = psDGN->abyElem[44] + psDGN->abyElem[45]*256;        }      break;      case DGNT_BSPLINE_SURFACE_BOUNDARY:        {          DGNElemBSplineSurfaceBoundary *psBounds;          int numverts = psDGN->abyElem[38] + psDGN->abyElem[39]*256;          psBounds = (DGNElemBSplineSurfaceBoundary *)            CPLCalloc(sizeof(DGNElemBSplineSurfaceBoundary)+                      (numverts-1)*sizeof(DGNPoint), 1);          psElement = (DGNElemCore *) psBounds;          psElement->stype = DGNST_BSPLINE_SURFACE_BOUNDARY;          DGNParseCore( psDGN, psElement );          // Read B-Spline surface boundary          psBounds->number = psDGN->abyElem[36] + psDGN->abyElem[37]*256;          psBounds->numverts = numverts;          for (int i=0;i<psBounds->numverts;i++) {            psBounds->vertices[i].x = DGN_INT32( psDGN->abyElem + 40 + i*8 );            psBounds->vertices[i].y = DGN_INT32( psDGN->abyElem + 44 + i*8 );            psBounds->vertices[i].z = 0;          }        }      break;      case DGNT_BSPLINE_KNOT:      case DGNT_BSPLINE_WEIGHT_FACTOR:        {          DGNElemKnotWeight *psArray;          // FIXME: Is it OK to assume that the # of elements corresponds          // directly to the element size? kintel 20051215.          int attr_bytes = psDGN->nElemBytes -             (psDGN->abyElem[30] + psDGN->abyElem[31]*256)*2 - 32;          int numelems = (psDGN->nElemBytes - 36 - attr_bytes)/4;          psArray = (DGNElemKnotWeight *)            CPLCalloc(sizeof(DGNElemKnotWeight) + (numelems-1)*sizeof(float), 1);          psElement = (DGNElemCore *) psArray;          psElement->stype = DGNST_KNOT_WEIGHT;          DGNParseCore( psDGN, psElement );          // Read array          for (int i=0;i<numelems;i++) {            psArray->array[i] =               1.0f * DGN_INT32(psDGN->abyElem + 36 + i*4) / ((1L << 31) - 1);          }        }      break;      case DGNT_SHARED_CELL_DEFN:      {          DGNElemSharedCellDefn *psShared;          psShared = (DGNElemSharedCellDefn *)               CPLCalloc(sizeof(DGNElemSharedCellDefn),1);          psElement = (DGNElemCore *) psShared;          psElement->stype = DGNST_SHARED_CELL_DEFN;          DGNParseCore( psDGN, psElement );          psShared->totlength = psDGN->abyElem[36] + psDGN->abyElem[37] * 256;      }      break;      default:      {          psElement = (DGNElemCore *) CPLCalloc(sizeof(DGNElemCore),1);          psElement->stype = DGNST_CORE;          DGNParseCore( psDGN, psElement );      }      break;    }/* -------------------------------------------------------------------- *//*      If the element structure type is "core" or if we are running    *//*      in "capture all" mode, record the complete binary image of      *//*      the element.                                                    *//* -------------------------------------------------------------------- */    if( psElement->stype == DGNST_CORE         || (psDGN->options & DGNO_CAPTURE_RAW_DATA) )    {        psElement->raw_bytes = psDGN->nElemBytes;        psElement->raw_data = (unsigned char *)CPLMalloc(psElement->raw_bytes);        memcpy( psElement->raw_data, psDGN->abyElem, psElement->raw_bytes );    }/* -------------------------------------------------------------------- *//*      Collect some additional generic information.                    *//* -------------------------------------------------------------------- */    psElement->element_id = psDGN->next_element_id - 1;    psElement->offset = VSIFTell( psDGN->fp ) - psDGN->nElemBytes;    psElement->size = psDGN->nElemBytes;    return psElement;}/************************************************************************//*                           DGNReadElement()                           *//************************************************************************//** * Read a DGN element. * * This function will return the next element in the file, starting with the * first.  It is affected by DGNGotoElement() calls.  * * The element is read into a structure which includes the DGNElemCore  * structure.  It is expected that applications will inspect the stype * field of the returned DGNElemCore and use it to cast the pointer to the * appropriate element structure type such as DGNElemMultiPoint.  * * @param hDGN the handle of the file to read from. * * @return pointer to element structure, or NULL on EOF or processing error. * The structure should be freed with DGNFreeElement() when no longer needed. */DGNElemCore *DGNReadElement( DGNHandle hDGN ){    DGNInfo     *psDGN = (DGNInfo *) hDGN;    DGNElemCore *psElement = NULL;    int         nType, nLevel;    int         bInsideFilter;/* -------------------------------------------------------------------- *//*      Load the element data into the current buffer.  If a spatial    *//*      filter is in effect, loop until we get something within our     *//*      spatial constraints.                                            *//* -------------------------------------------------------------------- */    do {         bInsideFilter = TRUE;        if( !DGNLoadRawElement( psDGN, &nType, &nLevel ) )            return NULL;                if( psDGN->has_spatial_filter )        {            GUInt32     nXMin, nXMax, nYMin, nYMax;                        if( !psDGN->sf_converted_to_uor )                DGNSpatialFilterToUOR( psDGN );            if( !DGNGetRawExtents( psDGN, nType, NULL,                                   &nXMin, &nYMin, NULL,                                   &nXMax, &nYMax, NULL ) )            {                /* If we don't have spatial characterists for the element                   we will pass it through. */                bInsideFilter = TRUE;            }            else if( nXMin > psDGN->sf_max_x                     || nYMin > psDGN->sf_max_y                     || nXMax < psDGN->sf_min_x                     || nYMax < psDGN->sf_min_y )                bInsideFilter = FALSE;            /*            ** We want to select complex elements based on the extents of            ** the header, not the individual elements.            */            if( nType == DGNT_COMPLEX_CHAIN_HEADER                || nType == DGNT_COMPLEX_SHAPE_HEADER )

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?