Ejemplo n.º 1
0
/******************************************************************************
  The format is roughly as follows (everything is big-endian):

   size     description
   -------------------------------------------
   byte     subtitle channel (0..7) in bits 0-3
   byte     subtitle packet number of this subtitle image 0-N,
            if the subtitle packet is complete, the top bit of the byte is 1.
   u_int16  subtitle image number
   u_int16  length in bytes of the rest
   byte     option flags, unknown meaning except bit 3 (0x08) indicates
            presence of the duration field
   byte     unknown
   u_int32  duration in 1/90000ths of a second (optional), start time
            is as indicated by the PTS in the PES header
   u_int32  xpos
   u_int32  ypos
   u_int32  width (must be even)
   u_int32  height (must be even)
   byte[16] palette, 4 palette entries, each contains values for
            Y, U, V and transparency, 0 standing for transparent
   byte     command,
            cmd>>6==1 indicates shift
            (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)
   u_int32  shift duration in 1/90000ths of a second
   u_int16  offset of odd-numbered scanlines - subtitle images are
            given in interlace order
   byte[]   limited RLE image data in interlace order (0,2,4... 1,3,5) with
            2-bits per palette number
******************************************************************************/
static void ParseHeader( decoder_t *p_dec, block_t *p_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    uint8_t *p = p_block->p_buffer;
    uint8_t i_options, i_options2, i_cmd, i_cmd_arg;
    int i;

    p_sys->i_spu_size = GETINT16(p);
    i_options  = *p++;
    i_options2 = *p++;

    if( i_options & 0x08 ) {
        p_sys->i_duration = GETINT32(p);
    }
    else p_sys->i_duration = 0; /* Ephemer subtitle */
    p_sys->i_duration *= 100 / 9;

    p_sys->i_x_start = GETINT16(p);
    p_sys->i_y_start = GETINT16(p);
    p_sys->i_width   = GETINT16(p);
    p_sys->i_height  = GETINT16(p);

    for( i = 0; i < 4; i++ )
    {
        p_sys->p_palette[i][0] = *p++; /* Y */
        p_sys->p_palette[i][2] = *p++; /* Cr / V */
        p_sys->p_palette[i][1] = *p++; /* Cb / U */
        p_sys->p_palette[i][3] = *p++; /* T */
    }

    i_cmd = *p++;
    /* We do not really know this, FIXME */
    if( i_cmd ) {
        i_cmd_arg = GETINT32(p);
    }

    /* Actually, this is measured against a different origin, so we have to
     * adjust it */
    p_sys->second_field_offset = GETINT16(p);
    p_sys->i_image_offset  = p - p_block->p_buffer;
    p_sys->i_image_length  = p_sys->i_spu_size - p_sys->i_image_offset;
    p_sys->metadata_length = p_sys->i_image_offset;

    if( p_sys->i_debug & DECODE_DBG_PACKET )
    {
        msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
                 "spu size: %zu, duration: %"PRIu64" (d:%zu p:%"PRIu16")",
                 p_sys->i_x_start, p_sys->i_y_start,
                 p_sys->i_width, p_sys->i_height,
                 p_sys->i_spu_size, p_sys->i_duration,
                 p_sys->i_image_length, p_sys->i_image_offset);

        for( i = 0; i < 4; i++ )
        {
            msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
                     p_sys->p_palette[i][3], p_sys->p_palette[i][0],
                     p_sys->p_palette[i][1], p_sys->p_palette[i][2] );
        }
    }
}
Ejemplo n.º 2
0
//解密运算,inputSize必须为128,192,256位
void Decrypt(RijndaelContextPtr context,void* input)
{
	int round;
	//明文的最大长度
	unsigned long state[8] = {0};
	unsigned char* inputStringPtr = (unsigned char*)input;
	unsigned int nb = context->nb;
	state[0] = GETINT32(inputStringPtr,0,nb);
	state[1] = GETINT32(inputStringPtr,1,nb);
	state[2] = GETINT32(inputStringPtr,2,nb);
	state[3] = GETINT32(inputStringPtr,3,nb);
	if (nb >= (KeySize_192/4))
	{
		state[4] = GETINT32(inputStringPtr,4,nb);
		state[5] = GETINT32(inputStringPtr,5,nb);
	}

	if (nb >= (KeySize_256/4))
	{
		state[6] = GETINT32(inputStringPtr,6,nb);
		state[7] = GETINT32(inputStringPtr,7,nb);
	}
	InvAddRoundKey(context,context->nr,state);
	InvShiftRow(context,state);
	InvSubByte(context,state);
	for (round = (context->nr-1); round > 0; round--)
	{
		InvAddRoundKey(context,round,state);
		InvMixColumn(context,state);
		InvShiftRow(context,state);
		InvSubByte(context,state);
	}
	InvAddRoundKey(context,0,state);
	StateToChars((unsigned char*)input,state,context->nb);
}
Ejemplo n.º 3
0
void KeyExpansion(RijndaelContextPtr context)
{
	int i;
	unsigned int tmp;
	//256位有32个字节,8个字长
	//密钥字长
	int nk = context->nk;
	//明文字长
	int nb = context->nb;
	//轮数
	int nr = context->nr;
	unsigned char* keyPtr = context->cryptKey;

	//nr最大为14,nb最大为8,则需要的矩阵列为nb*(nr+1)=8*15=120
	//轮密钥
	//unsigned long roundKey[120] = {0};
	context->roundKey[0] = GETINT32(keyPtr,0,nk);//第一列
	context->roundKey[1] = GETINT32(keyPtr,1,nk);//第二列
	context->roundKey[2] = GETINT32(keyPtr,2,nk);//第三列
	context->roundKey[3] = GETINT32(keyPtr,3,nk);//第四列
	if (nk >= (KeySize_192/4))
	{
		context->roundKey[4] = GETINT32(keyPtr,4,nk);
		context->roundKey[5] = GETINT32(keyPtr,5,nk);
	} 
	else if (nk >= (KeySize_256/4))
	{
		context->roundKey[6] = GETINT32(keyPtr,6,nk);
		context->roundKey[7] = GETINT32(keyPtr,7,nk);
	}

	//轮数为明文和密文中长度更大值的字长+4
	for (i = nk;i<(nb*(nr+1)); i++)
	{
		tmp = context->roundKey[i-1];
		if (i % nk == 0)
		{
			tmp = ROTL(tmp,8,32);
			tmp = SUBBYTE(tmp);
			tmp ^= rcon[i / nk];
		}
		else if ((nk > (KeySize_192/4)) && (i%4 == 0))
		{
			tmp = SUBBYTE(tmp);
		}
		context->roundKey[i] = context->roundKey[i - nk] ^ tmp;
	}
	//将不需要的清0
	memset(&context->roundKey[nb*(nr+1)],0,sizeof(context->roundKey) - sizeof(context->roundKey[0]) * (nb*(nr+1)));
	//轮密钥还可以加强,扩展
}
Ejemplo n.º 4
0
ErrorCode ReadCCMIO::read_gids_and_types(CCMIOID /* problemID */,
                                           CCMIOID topologyID,
                                           std::vector<EntityHandle> &cells) 
{
    // get the cells entity and number of cells
  CCMIOSize_t dum_cells;
  int num_cells;
  CCMIOError error = kCCMIONoErr;
  CCMIOID cellsID, mapID;
  CCMIOGetEntity(&error, topologyID, kCCMIOCells, 0, &cellsID);
  CCMIOEntitySize(&error, cellsID, &dum_cells, NULL);
  num_cells = GETINT32(dum_cells);

    // check the number of cells against how many are in the cell array
  if (num_cells != (int)cells.size())
    CHKERR(MB_FAILURE, "Number of cells doesn't agree.");

    // read the gid map and set global ids
  std::vector<int> cell_gids(num_cells);
  CCMIOReadCells(&error, cellsID, &mapID, NULL,
                 CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CCMIOReadMap(&error, mapID, &cell_gids[0], 
               CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Couldn't read cells or cell id map.");

  ErrorCode rval = mbImpl->tag_set_data(mGlobalIdTag, &cells[0], 
                                          cells.size(), &cell_gids[0]);
  CHKERR(rval, "Couldn't set gids tag.");

    // now read cell material types; reuse cell_gids
  CCMIOReadCells(&error, cellsID, NULL, &cell_gids[0],
                 CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Trouble reading cell types.");

    // create the matsets
  std::map<int, Range> matset_ents;
  for (int i = 0; i < num_cells; i++)
    matset_ents[cell_gids[i]].insert(cells[i]);

  for (std::map<int, Range>::iterator mit = matset_ents.begin(); mit != matset_ents.end(); mit++) {
    EntityHandle matset;
    rval = mbImpl->create_meshset(MESHSET_SET, matset);
    CHKERR(rval, "Couldn't create material set.");
    newMatsets[mit->first] = matset;
    
    rval = mbImpl->add_entities(matset, mit->second);
    CHKERR(rval, "Couldn't add entities to material set.");
  }
  
  return MB_SUCCESS;
}
Ejemplo n.º 5
0
//加密运算,inputSize必须为128,192,256位
void Encrypt(RijndaelContextPtr context,void* input)
{
	unsigned int round;
	//明文的最大长度
	unsigned long state[8] = {0};
	unsigned char* inputStringPtr = (unsigned char*)input;
	unsigned int nb = context->nb;
	//经过这个过程,由a0 a1 a2 a3 a4 a5组成的字节序列就组成了
	// a0 a4 a8  a12 a16 ...
	// a1 a5 a9  a13 a17 ...
	// a2 a6 a10 a14 a18 ...
	// a3 a7 a11 a15 a19 ...
	//这样的字节矩阵
	state[0] = GETINT32(inputStringPtr,0,nb);
	state[1] = GETINT32(inputStringPtr,1,nb);
	state[2] = GETINT32(inputStringPtr,2,nb);
	state[3] = GETINT32(inputStringPtr,3,nb);
	if (nb >= (KeySize_192/4))
	{
		state[4] = GETINT32(inputStringPtr,4,nb);
		state[5] = GETINT32(inputStringPtr,5,nb);
	}

	if (nb >= (KeySize_256/4))
	{
		state[6] = GETINT32(inputStringPtr,6,nb);
		state[7] = GETINT32(inputStringPtr,7,nb);
	}
	AddRoundKey(context,0,state);
	for (round = 1; round<context->nr; round++)
	{
		SubByte(context,state);
		ShiftRow(context,state);
		MixColumn(context,state);
		AddRoundKey(context,round,state);
	}
	SubByte(context,state);
	ShiftRow(context,state);
	AddRoundKey(context,context->nr,state);
	//就这个格式输出的密文,其实也没有关系的
	//将格式纠正
	StateToChars((unsigned char*)input,state,context->nb);
}
Ejemplo n.º 6
0
ErrorCode ReadCCMIO::read_topology_types(CCMIOID &topologyID, 
                                         std::map<int,int> &cell_topo_types) 
{
  CCMIOError error = kCCMIONoErr;
  CCMIOID cellID, mapID;
  CCMIOSize_t ncells;
  CCMIOGetEntity(&error, topologyID, kCCMIOCells, 0, &cellID);
  CCMIOEntitySize(&error, cellID, &ncells, NULL);
  int num_cells = GETINT32(ncells);

    // first, do a dummy read to see if we even have topo types in this mesh
  int dum_int;
  CCMIOReadOpt1i(&error, cellID, "CellTopologyType", &dum_int,
                 CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOStart)+1);
  if (kCCMIONoErr != error) return MB_SUCCESS;
  
    // ok, we have topo types; first get the map node
  std::vector<int> dum_ints(num_cells);
  CCMIOReadCells(&error, cellID, &mapID, &dum_ints[0],
                 CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOStart)+1);
  CHKCCMERR(error, "Failed to get the map node.");

    // now read the map
  CCMIOReadMap(&error, mapID, &dum_ints[0],
               CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Failed to get cell ids.");
  int i;
  for (i = 0; i < num_cells; i++) cell_topo_types[dum_ints[i]] = 0;

    // now read the cell topo types for real, reusing cell_topo_types
  std::vector<int> topo_types(num_cells);
  CCMIOReadOpt1i(&error, cellID, "CellTopologyType", &topo_types[0],
                 CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Failed to get cell topo types.");
  std::map<int,int>::iterator mit;
  for (i = 0; i < num_cells; i++) 
    cell_topo_types[dum_ints[i]] = topo_types[i];
  
  return MB_SUCCESS;
}
Ejemplo n.º 7
0
ErrorCode ReadCCMIO::read_faces(CCMIOID faceID, 
                                CCMIOEntity bdy_or_int,
                                TupleList &vert_map,
                                TupleList &face_map
#ifndef TUPLE_LIST
                                  ,SenseList &sense_map
#endif
                                  , Range *new_faces)
{
  if (kCCMIOInternalFaces != bdy_or_int && kCCMIOBoundaryFaces != bdy_or_int)
    CHKERR(MB_FAILURE, "Face type isn't boundary or internal.");

  CCMIOSize_t dum_faces;
  CCMIOError error = kCCMIONoErr;
  CCMIOEntitySize(&error, faceID, &dum_faces, NULL);
  int num_faces = GETINT32(dum_faces);
  
    // get the size of the face connectivity array (not really a straight connect
    // array, has n, connect(n), ...)
  CCMIOSize_t farray_size = CCMIOSIZEC(0);
  CCMIOReadFaces(&error, faceID, bdy_or_int, NULL, &farray_size, NULL,
                 CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Trouble reading face connectivity length.");
    

    // allocate vectors for holding farray and cells for each face; use new for finer
    // control of de-allocation
  int num_sides = (kCCMIOInternalFaces == bdy_or_int ? 2 : 1);
  int *farray = new int[GETINT32(farray_size)];

    // read farray and make the faces
  CCMIOID mapID;
  CCMIOReadFaces(&error, faceID, bdy_or_int, &mapID, NULL,
                 farray, CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Trouble reading face connectivity.");

  std::vector<EntityHandle> face_handles;
  ErrorCode rval = make_faces(farray, vert_map, face_handles, num_faces);
  CHKERR(rval, NULL);

    // read face cells and make tuples
  int *face_cells;
  if (num_sides*num_faces < farray_size) face_cells = new int[num_sides*num_faces];
  else face_cells = farray;
  CCMIOReadFaceCells(&error, faceID, bdy_or_int, face_cells,
                     CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Trouble reading face cells.");

  int *tmp_ptr = face_cells;
  for (unsigned int i = 0; i < face_handles.size(); i++) {
#ifdef TUPLE_LIST
    short forward = 1, reverse = -1;
    face_map.push_back(&forward, tmp_ptr++, &face_handles[i], NULL);
    if (2 == num_sides)
      face_map.push_back(&reverse, tmp_ptr++, &face_handles[i], NULL);
#else
    face_map[*tmp_ptr].push_back(face_handles[i]);
    sense_map[*tmp_ptr++].push_back(1);
    if (2 == num_sides) {
      face_map[*tmp_ptr].push_back(face_handles[i]);
      sense_map[*tmp_ptr++].push_back(-1);
    }
#endif
  }

    // now read & set face gids, reuse face_cells 'cuz we know it's big enough
  CCMIOReadMap(&error, mapID, face_cells, CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Trouble reading face gids.");

  rval = mbImpl->tag_set_data(mGlobalIdTag, &face_handles[0], face_handles.size(), face_cells);
  CHKERR(rval, "Couldn't set face global ids.");

    // make a neumann set for these faces if they're all in a boundary face set
  if (kCCMIOBoundaryFaces == bdy_or_int) {
    EntityHandle neuset;
    rval = mbImpl->create_meshset(MESHSET_SET, neuset);
    CHKERR(rval, "Failed to create neumann set.");

      // don't trust entity index passed in
    int index;
    CCMIOGetEntityIndex(&error, faceID, &index);
    newNeusets[index] = neuset;

    rval = mbImpl->add_entities(neuset, &face_handles[0], face_handles.size());
    CHKERR(rval, "Failed to add faces to neumann set.");

      // now tag as neumann set; will add id later
    int dum_val = 0;
    rval = mbImpl->tag_set_data(mNeumannSetTag, &neuset, 1, &dum_val);
    CHKERR(rval, "Failed to tag neumann set.");
  }

  if (new_faces) {
    std::sort(face_handles.begin(), face_handles.end());
    std::copy(face_handles.rbegin(), face_handles.rend(), range_inserter(*new_faces));
  }
  
  return MB_SUCCESS;
}
Ejemplo n.º 8
0
ErrorCode ReadCCMIO::load_matset_data(CCMIOID problemID) 
{
    // make sure there are matsets
  if (newMatsets.empty()) return MB_SUCCESS;
  
    // ... walk through each cell type
  CCMIOSize_t i = CCMIOSIZEC(0);
  CCMIOID next;
  std::string opt_string;
  CCMIOError error = kCCMIONoErr;
  
  while (CCMIONextEntity(NULL, problemID, kCCMIOCellType, &i, &next)
         == kCCMIONoErr) {
      // get index, corresponding set, and label with material set tag
    int mindex;
    CCMIOGetEntityIndex(&error, next, &mindex);
    std::map<int,EntityHandle>::iterator mit = newMatsets.find(mindex);
    if (mit == newMatsets.end()) 
        // no actual faces for this matset; continue to next
      continue;
    
    EntityHandle dum_ent = mit->second;
    ErrorCode rval = mbImpl->tag_set_data(mMaterialSetTag, &dum_ent, 1, &mindex);
    CHKERR(rval, "Trouble setting material set tag.");

      // set name
    CCMIOSize_t len;
    CCMIOEntityLabel(&error, next, &len, NULL);
    std::vector<char> opt_string2(GETINT32(len)+1, '\0');
    CCMIOEntityLabel(&error, next, NULL, &opt_string2[0]);
    if (opt_string2.size() >= NAME_TAG_SIZE) opt_string2[NAME_TAG_SIZE-1] = '\0';
    else (opt_string2.resize(NAME_TAG_SIZE, '\0'));
    rval = mbImpl->tag_set_data(mNameTag, &dum_ent, 1, &opt_string2[0]);
    CHKERR(rval, "Trouble setting name tag for material set.");

      // material id
    rval = get_int_option("MaterialId", dum_ent, mMaterialIdTag, next);
    CHKERR(rval, "Trouble getting MaterialId tag.");
    
    rval = get_str_option("MaterialType", dum_ent, mMaterialTypeTag, next);
    CHKERR(rval, "Trouble getting MaterialType tag.");
    
    rval = get_int_option("Radiation", dum_ent, mRadiationTag, next);
    CHKERR(rval, "Trouble getting Radiation option.");

    rval = get_int_option("PorosityId", dum_ent, mPorosityIdTag, next);
    CHKERR(rval, "Trouble getting PorosityId option.");

    rval = get_int_option("SpinId", dum_ent, mSpinIdTag, next);
    CHKERR(rval, "Trouble getting SpinId option.");

    rval = get_int_option("GroupId", dum_ent, mGroupIdTag, next);
    CHKERR(rval, "Trouble getting GroupId option.");

    rval = get_int_option("ColorIdx", dum_ent, mColorIdxTag, next);
    CHKERR(rval, "Trouble getting ColorIdx option.");

    rval = get_int_option("ProcessorId", dum_ent, mProcessorIdTag, next);
    CHKERR(rval, "Trouble getting ProcessorId option.");

    rval = get_int_option("LightMaterial", dum_ent, mLightMaterialTag, next);
    CHKERR(rval, "Trouble getting LightMaterial option.");

    rval = get_int_option("FreeSurfaceMaterial", dum_ent, mFreeSurfaceMaterialTag, next);
    CHKERR(rval, "Trouble getting FreeSurfaceMaterial option.");

    rval = get_dbl_option("Thickness", dum_ent, mThicknessTag, next);
    CHKERR(rval, "Trouble getting Thickness option.");
  }

  return MB_SUCCESS;
}
Ejemplo n.º 9
0
ErrorCode ReadCCMIO::read_vertices(CCMIOSize_t /* proc */, CCMIOID /* processorID */, CCMIOID verticesID,
                                   CCMIOID /* topologyID */, 
                                   Range *verts, TupleList &vert_map) 
{
  CCMIOError error = kCCMIONoErr;
  
    // pre-read the number of vertices, so we can pre-allocate & read directly in
  CCMIOSize_t nverts = CCMIOSIZEC(0);
  CCMIOEntitySize(&error, verticesID, &nverts, NULL);
  CHKCCMERR(error, "Couldn't get number of vertices.");

    // get # dimensions
  CCMIOSize_t dims;
  float scale;
  CCMIOReadVerticesf(&error, verticesID, &dims, NULL, NULL, NULL, CCMIOINDEXC(0), CCMIOINDEXC(1));
  CHKCCMERR(error, "Couldn't get number of dimensions.");

    // allocate vertex space
  EntityHandle node_handle = 0;
  std::vector<double*> arrays;
  readMeshIface->get_node_coords(3, GETINT32(nverts), MB_START_ID, node_handle, arrays);

    // read vertex coords
  CCMIOID mapID;
  std::vector<double> tmp_coords(GETINT32(dims)*GETINT32(nverts));
  CCMIOReadVerticesd(&error, verticesID, &dims, &scale, &mapID, &tmp_coords[0], 
                     CCMIOINDEXC(0), CCMIOINDEXC(0+nverts));
  CHKCCMERR(error, "Trouble reading vertex coordinates.");

    // copy interleaved coords into moab blocked coordinate space
  int i = 0, threei = 0;
  for (; i < nverts; i++) {
    arrays[0][i] = tmp_coords[threei++];
    arrays[1][i] = tmp_coords[threei++];
    if (3 == GETINT32(dims)) arrays[2][i] = tmp_coords[threei++];
    else arrays[2][i] = 0.0;
  }

    // scale, if necessary
  if (1.0 != scale) {
    for(i = 0; i < nverts; i++) {
      arrays[0][i] *= scale;
      arrays[1][i] *= scale;
      if (3 == GETINT32(dims)) arrays[2][i] *= scale;
    }
  }

    // read gids for vertices
  std::vector<int> gids(GETINT32(nverts));
  CCMIOReadMap(&error, mapID, &gids[0], CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
  CHKCCMERR(error, "Trouble reading vertex global ids.");

    // put new vertex handles into range, and set gids for them
  Range new_verts(node_handle, node_handle+nverts-1);
  ErrorCode rval = mbImpl->tag_set_data(mGlobalIdTag, new_verts, &gids[0]);
  CHKERR(rval, "Couldn't set gids on vertices.");
  
    // pack vert_map with global ids and handles for these vertices
#ifdef TUPLE_LIST
  vert_map.resize(GETINT32(nverts));
  for (i = 0; i < GETINT32(nverts); i++) {
    vert_map.push_back(NULL, &gids[i], &node_handle, NULL);
#else
  for (i = 0; i < GETINT32(nverts); i++) {
    (vert_map[gids[i]]).push_back(node_handle);
#endif
    node_handle += 1;
  }
  
  if (verts) verts->merge(new_verts);

  return MB_SUCCESS;
}
  
ErrorCode ReadCCMIO::get_processors(CCMIOID stateID, 
                                    CCMIOID &processorID, CCMIOID &verticesID,
                                    CCMIOID &topologyID, CCMIOID &solutionID,
                                    std::vector<CCMIOSize_t> &procs,
                                    bool & /* has_solution */) 
{
  CCMIOSize_t proc = CCMIOSIZEC(0);
  CCMIOError error = kCCMIONoErr;
  
  CCMIONextEntity(&error, stateID, kCCMIOProcessor, &proc, &processorID);
  CHKCCMERR(error, NULL);
  if (CCMIOReadProcessor(NULL, processorID, &verticesID, 
                         &topologyID, NULL, &solutionID) != kCCMIONoErr) {
      // Maybe no solution;  try again
    CCMIOReadProcessor(&error, processorID, &verticesID, 
                       &topologyID, NULL, NULL);
    hasSolution = false;
  }
  CHKCCMERR(error, NULL);
  
  procs.push_back(proc);
  
  return MB_SUCCESS;
}