Example #1
0
/*
Make paying for the trip fair for all students.
 */
int main() {
  while(true) {
    // Parse input:
    std::string line;
    std::getline(std::cin, line);

    int N = readInt(line);
    if(N == 0)
      return 0;

    int paid[10000];
    int sum = 0;
    for(int i = 0; i < N; ++i) {
      std::getline(std::cin, line);      
      int val = readInt(line);
      paid[i] = val;
      sum += val;
    }

    // Compute output:
    int avg = (sum+N/2)/N;
    //std::cerr << " AVERAGE: " << avg << std::endl;
    int pay1 = computeFor(avg-1, avg, N, paid);
    int pay2 = computeFor(avg, avg+1, N, paid);
    int pay = pay1 < pay2 ? pay1 : pay2;

    //std::cerr << " TOTAL TRANSACTION: " << pay << std::endl;
 
    printf("$%i.%02i\n", pay/100, pay%100);
    //std::cerr << " " << pay << std::endl;
  }
}
Example #2
0
CallLinkStatus CallLinkStatus::computeFor(
    CodeBlock* profiledBlock, unsigned bytecodeIndex, const CallLinkInfoMap& map)
{
    ConcurrentJITLocker locker(profiledBlock->m_lock);

    UNUSED_PARAM(profiledBlock);
    UNUSED_PARAM(bytecodeIndex);
    UNUSED_PARAM(map);
#if ENABLE(DFG_JIT)
    if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache))
            || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint))
            || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable)))
        return takesSlowPath();

    CallLinkInfo* callLinkInfo = map.get(CodeOrigin(bytecodeIndex));
    if (!callLinkInfo)
        return computeFromLLInt(locker, profiledBlock, bytecodeIndex);

    CallLinkStatus result = computeFor(locker, *callLinkInfo);
    if (!result)
        return computeFromLLInt(locker, profiledBlock, bytecodeIndex);

    if (profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction)))
        result.makeClosureCall();

    return result;
#else
    return CallLinkStatus();
#endif
}
Example #3
0
void CallLinkStatus::computeDFGStatuses(
    CodeBlock* dfgCodeBlock, CallLinkStatus::ContextMap& map)
{
#if ENABLE(DFG_JIT)
    RELEASE_ASSERT(dfgCodeBlock->jitType() == JITCode::DFGJIT);
    CodeBlock* baselineCodeBlock = dfgCodeBlock->alternative();
    for (auto iter = dfgCodeBlock->callLinkInfosBegin(); !!iter; ++iter) {
        CallLinkInfo& info = **iter;
        CodeOrigin codeOrigin = info.codeOrigin;

        bool takeSlowPath;
        bool badFunction;

        // Check if we had already previously made a terrible mistake in the FTL for this
        // code origin. Note that this is approximate because we could have a monovariant
        // inline in the FTL that ended up failing. We should fix that at some point by
        // having data structures to track the context of frequent exits. This is currently
        // challenging because it would require creating a CodeOrigin-based database in
        // baseline CodeBlocks, but those CodeBlocks don't really have a place to put the
        // InlineCallFrames.
        CodeBlock* currentBaseline =
            baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, baselineCodeBlock);
        {
            ConcurrentJITLocker locker(currentBaseline->m_lock);
            takeSlowPath =
                currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCache, ExitFromFTL))
                || currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCacheWatchpoint, ExitFromFTL))
                || currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadExecutable, ExitFromFTL));
            badFunction =
                currentBaseline->hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadFunction, ExitFromFTL));
        }

        {
            ConcurrentJITLocker locker(dfgCodeBlock->m_lock);
            if (takeSlowPath)
                map.add(info.codeOrigin, takesSlowPath());
            else {
                CallLinkStatus status = computeFor(locker, info);
                if (status.isSet()) {
                    if (badFunction)
                        status.makeClosureCall();
                    map.add(info.codeOrigin, status);
                }
            }
        }
    }
#else
    UNUSED_PARAM(dfgCodeBlock);
#endif // ENABLE(DFG_JIT)

    if (verbose) {
        dataLog("Context map:\n");
        ContextMap::iterator iter = map.begin();
        ContextMap::iterator end = map.end();
        for (; iter != end; ++iter) {
            dataLog("    ", iter->key, ":\n");
            dataLog("        ", iter->value, "\n");
        }
    }
}
Example #4
0
GetByIdStatus GetByIdStatus::computeFor(
    CodeBlock* profiledBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap,
    StubInfoMap& dfgMap, CodeOrigin codeOrigin, StringImpl* uid)
{
#if ENABLE(DFG_JIT)
    if (dfgBlock) {
        GetByIdStatus result;
        {
            ConcurrentJITLocker locker(dfgBlock->m_lock);
            result = computeForStubInfo(locker, dfgBlock, dfgMap.get(codeOrigin), uid);
        }
        
        if (result.takesSlowPath())
            return result;
    
        {
            ConcurrentJITLocker locker(profiledBlock->m_lock);
            if (hasExitSite(locker, profiledBlock, codeOrigin.bytecodeIndex, ExitFromFTL))
                return GetByIdStatus(TakesSlowPath, true);
        }
        
        if (result.isSet())
            return result;
    }
#else
    UNUSED_PARAM(dfgBlock);
    UNUSED_PARAM(dfgMap);
#endif

    return computeFor(profiledBlock, baselineMap, codeOrigin.bytecodeIndex, uid);
}
Example #5
0
PutByIdStatus PutByIdStatus::computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin codeOrigin, StringImpl* uid)
{
#if ENABLE(DFG_JIT)
    if (dfgBlock) {
        CallLinkStatus::ExitSiteData exitSiteData;
        {
            ConcurrentJITLocker locker(baselineBlock->m_lock);
            if (hasExitSite(locker, baselineBlock, codeOrigin.bytecodeIndex, ExitFromFTL))
                return PutByIdStatus(TakesSlowPath);
            exitSiteData = CallLinkStatus::computeExitSiteData(
                locker, baselineBlock, codeOrigin.bytecodeIndex, ExitFromFTL);
        }
            
        PutByIdStatus result;
        {
            ConcurrentJITLocker locker(dfgBlock->m_lock);
            result = computeForStubInfo(
                locker, dfgBlock, dfgMap.get(codeOrigin), uid, exitSiteData);
        }
        
        // We use TakesSlowPath in some cases where the stub was unset. That's weird and
        // it would be better not to do that. But it means that we have to defend
        // ourselves here.
        if (result.isSimple())
            return result;
    }
#else
    UNUSED_PARAM(dfgBlock);
    UNUSED_PARAM(dfgMap);
#endif

    return computeFor(baselineBlock, baselineMap, codeOrigin.bytecodeIndex, uid);
}
Example #6
0
CallLinkStatus CallLinkStatus::computeFor(
    CodeBlock* profiledBlock, CodeOrigin codeOrigin,
    const CallLinkInfoMap& baselineMap, const CallLinkStatus::ContextMap& dfgMap)
{
    auto iter = dfgMap.find(codeOrigin);
    if (iter != dfgMap.end())
        return iter->value;

    return computeFor(profiledBlock, codeOrigin.bytecodeIndex, baselineMap);
}
Example #7
0
CallLinkStatus CallLinkStatus::computeFor(
    const ConcurrentJITLocker& locker, CallLinkInfo& callLinkInfo, ExitSiteData exitSiteData)
{
    if (exitSiteData.m_takesSlowPath)
        return takesSlowPath();
    
    CallLinkStatus result = computeFor(locker, callLinkInfo);
    if (exitSiteData.m_badFunction)
        result.makeClosureCall();
    
    return result;
}
Example #8
0
CallLinkStatus CallLinkStatus::computeFor(
    const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, CallLinkInfo& callLinkInfo,
    ExitSiteData exitSiteData)
{
    CallLinkStatus result = computeFor(locker, profiledBlock, callLinkInfo);
    if (exitSiteData.m_badFunction)
        result.makeClosureCall();
    if (exitSiteData.m_takesSlowPath)
        result.m_couldTakeSlowPath = true;
    
    return result;
}
Example #9
0
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////JPEG SPECIFIC CODE HERE BELOW //////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
UINT8 EXTR::read_next_marker() {
	UINT8 tmp;

	tmp = read_8_bits();

	if (tmp != 0xff)
		return ERROR_INVALID_FILL_BYTE;

	do {
		tmp = read_8_bits();
		computeFor(1);
	} while (tmp == 0xff);

	return tmp; //SUCCESS;
}
Example #10
0
inline UINT8 EXTR::read_8_bits() {
	UINT8 inputValue;

	UINT8 alignment = (m_inputAdd & 0x3);
	if(alignment == 0 || !m_bufferValid) { // Address is a multiple of 4: need to read a new word from memory
		DeviceRead(JPEGRAM_ID, m_inputAdd & 0xFFFFFFFC, &m_inputBuffer[0], 4);
		m_bufferValid = true;
	}
	inputValue = m_inputBuffer[alignment];
	
	m_inputAdd+=1;
	
	computeFor(1);

	return inputValue;
}
Example #11
0
void CallLinkStatus::computeDFGStatuses(
    CodeBlock* dfgCodeBlock, CallLinkStatus::ContextMap& map)
{
#if ENABLE(DFG_JIT)
    RELEASE_ASSERT(dfgCodeBlock->jitType() == JITCode::DFGJIT);
    CodeBlock* baselineCodeBlock = dfgCodeBlock->alternative();
    for (auto iter = dfgCodeBlock->callLinkInfosBegin(); !!iter; ++iter) {
        CallLinkInfo& info = **iter;
        CodeOrigin codeOrigin = info.codeOrigin();
        
        // Check if we had already previously made a terrible mistake in the FTL for this
        // code origin. Note that this is approximate because we could have a monovariant
        // inline in the FTL that ended up failing. We should fix that at some point by
        // having data structures to track the context of frequent exits. This is currently
        // challenging because it would require creating a CodeOrigin-based database in
        // baseline CodeBlocks, but those CodeBlocks don't really have a place to put the
        // InlineCallFrames.
        CodeBlock* currentBaseline =
            baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, baselineCodeBlock);
        ExitSiteData exitSiteData;
        {
            ConcurrentJITLocker locker(currentBaseline->m_lock);
            exitSiteData = computeExitSiteData(
                locker, currentBaseline, codeOrigin.bytecodeIndex);
        }
        
        {
            ConcurrentJITLocker locker(dfgCodeBlock->m_lock);
            map.add(info.codeOrigin(), computeFor(locker, dfgCodeBlock, info, exitSiteData));
        }
    }
#else
    UNUSED_PARAM(dfgCodeBlock);
#endif // ENABLE(DFG_JIT)
    
    if (verbose) {
        dataLog("Context map:\n");
        ContextMap::iterator iter = map.begin();
        ContextMap::iterator end = map.end();
        for (; iter != end; ++iter) {
            dataLog("    ", iter->key, ":\n");
            dataLog("        ", iter->value, "\n");
        }
    }
}
Example #12
0
void EXTR::launch_face_detection(void) {
	if (GetVerbose())
		SpacePrint("EXTR: Launching Face Detection\n");
	
	if (++m_currentBitmapImage > MAX_NB_IMAGE)
		m_currentBitmapImage = 1;
	
	JMSG messageToFace;
	messageToFace.command = SCMD_BEGIN_FACE_DETECTION;
	messageToFace.param0 = m_decompressedImageAddr[m_currentBitmapImage-1];
	messageToFace.param1 = m_currentJPEGImageNo;
	computeFor(1);

	ModuleWrite(FACEDETECT_ID, SPACE_BLOCKING, &messageToFace);

	if (GetVerbose())
		SpacePrint("EXTR: Returned from launch face detection for image #%d\n", m_currentBitmapImage);
}
Example #13
0
CallLinkStatus CallLinkStatus::computeFor(
    const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, CallLinkInfo& callLinkInfo,
    ExitSiteData exitSiteData)
{
    CallLinkStatus result = computeFor(locker, profiledBlock, callLinkInfo);
    if (exitSiteData.badFunction) {
        if (result.isBasedOnStub()) {
            // If we have a polymorphic stub, then having an exit site is not quite so useful. In
            // most cases, the information in the stub has higher fidelity.
            result.makeClosureCall();
        } else {
            // We might not have a polymorphic stub for any number of reasons. When this happens, we
            // are in less certain territory, so exit sites mean a lot.
            result.m_couldTakeSlowPath = true;
        }
    }
    if (exitSiteData.takesSlowPath)
        result.m_couldTakeSlowPath = true;
    
    return result;
}
Example #14
0
CallLinkStatus CallLinkStatus::computeFor(
    CodeBlock* profiledBlock, unsigned bytecodeIndex, const CallLinkInfoMap& map)
{
    ConcurrentJITLocker locker(profiledBlock->m_lock);
    
    UNUSED_PARAM(profiledBlock);
    UNUSED_PARAM(bytecodeIndex);
    UNUSED_PARAM(map);
#if ENABLE(DFG_JIT)
    ExitSiteData exitSiteData = computeExitSiteData(locker, profiledBlock, bytecodeIndex);
    if (exitSiteData.m_takesSlowPath)
        return takesSlowPath();
    
    CallLinkInfo* callLinkInfo = map.get(CodeOrigin(bytecodeIndex));
    if (!callLinkInfo)
        return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
    
    return computeFor(locker, *callLinkInfo, exitSiteData);
#else
    return CallLinkStatus();
#endif
}
Example #15
0
GetByIdStatus GetByIdStatus::computeFor(
    CodeBlock* profiledBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap,
    StubInfoMap& dfgMap, CodeOrigin codeOrigin, UniquedStringImpl* uid)
{
#if ENABLE(DFG_JIT)
    if (dfgBlock) {
        CallLinkStatus::ExitSiteData exitSiteData;
        {
            ConcurrentJITLocker locker(profiledBlock->m_lock);
            exitSiteData = CallLinkStatus::computeExitSiteData(
                locker, profiledBlock, codeOrigin.bytecodeIndex);
        }
        
        GetByIdStatus result;
        {
            ConcurrentJITLocker locker(dfgBlock->m_lock);
            result = computeForStubInfoWithoutExitSiteFeedback(
                locker, dfgBlock, dfgMap.get(codeOrigin), uid, exitSiteData);
        }

        if (result.takesSlowPath())
            return result;
    
        {
            ConcurrentJITLocker locker(profiledBlock->m_lock);
            if (hasExitSite(locker, profiledBlock, codeOrigin.bytecodeIndex))
                return GetByIdStatus(TakesSlowPath, true);
        }
        
        if (result.isSet())
            return result;
    }
#else
    UNUSED_PARAM(dfgBlock);
    UNUSED_PARAM(dfgMap);
#endif

    return computeFor(profiledBlock, baselineMap, codeOrigin.bytecodeIndex, uid);
}
Example #16
0
//
//  EXTR::decode_interleaved_scan
//////////////////////////////////////////////////////////////////////////////
/// 
/// This is the loop that extracts the jpeg data
/// 
///
/// @return =>  UINT16  : SUCCESS (always)
///
/// @note   =>  
//////////////////////////////////////////////////////////////////////////////
UINT16 EXTR::decode_interleaved_scan() {
	UINT16 i, j, horizontal_mcus, vertical_mcus;
	space_uint2 k, number_of_image_components_in_frame;
	space_uint4 l, m, horizontal_sampling_factor, vertical_sampling_factor;

	JMSG msg;
	
	// use these shortcuts	
	horizontal_mcus = m_jpeg_decoder_structure.horizontal_mcus;
	vertical_mcus = m_jpeg_decoder_structure.vertical_mcus;
	number_of_image_components_in_frame = m_jpeg_decoder_structure.number_of_image_components_in_frame;

	//
	// The jpeg image is stored in minimal component units or mcu. Each unit represents
	// a luminance block (Y) or a chrominance block (C). Since this decoder only supports
	// files that are encoded in the YUV 4:2:0 format, MCUs are stored in groups of 6. 
	// The four first MCUs are luminance component. The two lasts are chrominance Cb and Cr
	// that are colour information for the 4 previous luminance blocks. 
	// This can be seen as follow:
	//
	//		 _____________
	//		|      |      |
	//		|  Y1  |  Y2  |
	//		|   ___|___   |  
	//		|  |   |   |  |
    //      |--|Cb | Cr|--|
    //      |  |___|___|  |
    //      |      |      |
	//		|  Y3  |  Y4  |
	//		|______|______|  
    //


	// we scan all the vertical & horizontal mcus
	for (i=1; i<=vertical_mcus; i++)
	//for (i=1; i<=vertical_mcus/2; i++)
	{
		for (j=1; j<=horizontal_mcus;j++)
		//for (j=1; j<=horizontal_mcus/4;j++)
		{		
			// every mcu is composed of 3 components Y, Cb and Cr
			for (k=0; k<number_of_image_components_in_frame; k ++)
			{
				vertical_sampling_factor = m_jpeg_decoder_structure.vertical_sampling_factor [k];
				horizontal_sampling_factor = m_jpeg_decoder_structure.horizontal_sampling_factor [k];

				computeFor(1);

				for (l=0; l<vertical_sampling_factor; l++)
				{
					for (m=0; m<horizontal_sampling_factor; m++)
					{
						
						// triggers a notification to huffman thread to start Huffman decoding
						m_currentHuffmanComponent = k;

						// send information to HUFF module
						msg.command = SCMD_HUFFMAN_MCU;
						msg.param0 = m_currentHuffmanComponent;
						msg.param1 = m_inputAdd;
						
						computeFor(1);

						// send over request to huffman module
						ModuleWrite(HUFF_ID, SPACE_BLOCKING, &msg);

						computeFor(1);

						ModuleRead(HUFF_ID, SPACE_BLOCKING, &msg);
						
						if (GetVerbose())
						{
							static int roulette = 1;
							switch (roulette)
							{
							case 1: //[
							case 5:
								SpacePrint("|\b");
								break;
							case 2:
							case 7:
								SpacePrint("/\b");
								break;
							case 3:
							case 6:
								SpacePrint("-\b");
								break;
							case 4:
							case 8:
								SpacePrint("\\\b");
								break;
							}

							if (++roulette > 8) roulette = 1;

						}

						if (GetVerbose())
							SpacePrint("EXTR: decode_interleave_scan returned i:%d j:%d k:%d l:%d m:%d\n", i, j, k, l, m);


						if (msg.command != SCMD_ACK)
						{
							SpacePrint("EXTRACTOR ERROR : decode_interleaved has received a FAIL %d from HUFFMAN module\n", msg.param0); //this->name(), msg.param0);
							sc_stop();
						}
						else

						{
							m_inputAdd = msg.param0;
							m_bufferValid = false;
						}

					}
				}
			}
		}
	}
		
	// (.)(.)
	//   <
	//  ____
	// \/  \/
	// when we get here, it's the end of the image!
	
	if (GetVerbose())
		SpacePrint("\n");

 	return SUCCESS;
}
Example #17
0
chunk *computeInstruction(ANTLR3_BASE_TREE *node) {
  debug(DEBUG_GENERATION, "\033[22;93mCompute instruction\033[0m");

  chunk *chunk, *tmp_chunk;
  int i, scope_tmp;

  static int scope = 0;


  switch (node->getType(node)) {

    case INTEGER :
    case STRING :
    case ID :
    case FUNC_CALL :
    case SUP    :
    case INF    :
    case SUP_EQ :
    case INF_EQ :
    case EQ     :
    case DIFF   :
    case AND :
    case OR :
    case MINUS :
    case PLUS :
    case DIV :
    case MULT :
    case NEG :
    case ASSIGNE :
      return computeExpr(node);


    case IF:
      return computeIf(node);

    case WHILE :
      return computeWhile(node);

    case FOR :
      return computeFor(node);


    case VAR_DECLARATION :
      return computeVarDeclaration(node);

    case FUNC_DECLARATION :
    case LET :
      enterScopeN(scope);

      scope_tmp = scope;
      scope = 0;

      switch (node->getType(node)) {
        case LET:
          chunk = computeLet(node);
          break;
        case FUNC_DECLARATION:
          chunk = computeFuncDeclaration(node);
          break;
      }

      scope = scope_tmp;
      scope++;

      leaveScope();

      return chunk;


    default:
      chunk = initChunk();

      // Compute all children
      for (i = 0; i < node->getChildCount(node); i++) {
        tmp_chunk = computeInstruction(node->getChild(node, i));
        appendChunks(chunk, tmp_chunk);
        // appendChunks replace chunk->registre with tmp_chunk's one
        // but freeChunk free the registre of tmp_chunk
        // we don't want chunk->registre to be overwritten !
        if (tmp_chunk != NULL)
          tmp_chunk->registre = -1;
        freeChunk(tmp_chunk);
      }

      return chunk;
  }
}
Example #18
0
void EXTR::thread_extract_jpeg() {
	UINT8 last_marker;
	UINT8 last_returned;
	
    bool end_of_jpeg;
    bool has_at_least_one_jpeg_succeeded;
	
	JMSG outmsg;
	JMSG inmsg;
	
	m_currentJPEGImageNo = 0;
	m_currentBitmapImage = 0;
	m_bufferValid  = false;

	// represents the distance between each jpeg image
	m_jpegDist	= JPEG_IMAGE_SPACER;
	
    has_at_least_one_jpeg_succeeded = false;

	// reset to 0 structures and data related to jpeg decompression
	initialize();

	while(1) {
       end_of_jpeg = false;

		//
		// selection of jpeg preloop - sets pointer on proper image 
		//
        m_currentJPEGImageNo++; 
		if (m_currentJPEGImageNo > MAX_NB_IMAGE)
        {
        	// either we stop when we finish processing the images...
        	launch_face_detection();
        	sc_stop();
			
			// ...or we loop forever (comment out the previous line)
			m_currentJPEGImageNo = 1; 
            if (has_at_least_one_jpeg_succeeded == false)
            {
               SpacePrint("........................................................\n");
               SpacePrint("JPEG DECODER : ALL IMAGES SET FOR DECOMPRESSION\n");
               SpacePrint("HAVE FAILED -- STOPPING\n");
               SpacePrint("........................................................\n");
                sc_stop();
            }
        }

		m_infoImageHeaderAdd = (m_currentJPEGImageNo-1) * m_jpegDist; 	
		m_inputAdd = m_infoImageHeaderAdd + INFO_IMAGE_HEADER;
		m_bufferValid = false;
		computeFor(1);

        if (GetVerbose())
        {
           SpacePrint("EXTR: ********************************************** \n");
           SpacePrint("EXTR: Decompressing JPEG IMAGE no %d\n", m_currentJPEGImageNo);
           SpacePrint("EXTR: Input Address: 0x%x\n", m_inputAdd);
           SpacePrint("EXTR: ********************************************** \n");
        }
        else
        {
           SpacePrint("***JPEG %d\n",m_currentJPEGImageNo);
        }

		//
		// decode jpeg!
		//
		while (!end_of_jpeg) 
		{
			
			//
			// JPEG information is stored in between MARKERS. Each marker tells about 
			// the upcoming information to be read from the data
			//
			// this section scans markers and execute appropriate code according
			// to last marker read
			
			last_marker = read_next_marker();
			computeFor(1);
			
			switch (last_marker)
			{
				
			//
			// START OF FRAME MARKER
			//
			case SOF0:
			case SOF1:
			case SOF2:

                has_at_least_one_jpeg_succeeded = true;
				m_jpeg_decoder_structure.sof = last_marker;

				last_returned = read_sof_marker ();
				if (last_returned != SUCCESS)
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: JPEG SOF DECODING ERROR no %d - skipping JPEG\n", last_returned); //, this->name(), last_returned);
					initialize();
					end_of_jpeg = true;
				}
					// write image header into memory
					// WORD 1 is X width
					// WORD 2 is Y height
					DeviceWrite(JPEGRAM_ID, m_infoImageHeaderAdd, &m_jpeg_decoder_structure.number_of_samples_per_line);
					DeviceWrite(JPEGRAM_ID, m_infoImageHeaderAdd+0x4ul, &m_jpeg_decoder_structure.number_of_lines);

	                if (GetVerbose())
                    {
					   SpacePrint("EXTR: JPEG STARTING DECOMPRESSION OF IMAGE no%d\n", m_currentJPEGImageNo);
                       SpacePrint("EXTR: Image size: %dx%d\n",
                                      m_jpeg_decoder_structure.number_of_samples_per_line, 
                                      m_jpeg_decoder_structure.number_of_lines);
                    }
                    else
                    {
					   SpacePrint("EXTR:JPEG%d\n", m_currentJPEGImageNo);
                    }


                    communicate_IJPEG(SCMD_NEW_IMAGE);
				//}
				
				break;
				

			//
			// START OF HUFFMAN TABLE MARKER AT 0xffc0
			//	
			case DHT: 
				
				outmsg.command = SCMD_HUFFMAN_DHT;
				outmsg.param0 = m_inputAdd;

				if (GetVerbose())
					SpacePrint("EXTR: Huffman Table found; sending address to HUFF module\n");

				ModuleWrite(HUFF_ID, SPACE_BLOCKING, &outmsg);

				computeFor(1);

				// wait for acknowledgement
				ModuleRead(HUFF_ID, SPACE_BLOCKING, &inmsg);

				if (GetVerbose())
					SpacePrint("EXTR: Return from blocking read - waiting Huffman ACK\n");

				
				// ack received with update with memory pointer
				if (inmsg.command == SCMD_ACK)
				{
					m_inputAdd = inmsg.param0;
					m_bufferValid = false;
				}
				else
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: JPEG DHT DECODING ERROR no %d - skipping JPEG\n", inmsg.param0); //this->name(), inmsg.param0);
					initialize();
					end_of_jpeg = true;
				}
				break;

			//
			// START OF SCAN MARKER (DATA) AT 0xffda
			//
			case SOS:
				skip_marker ();	
				// extract file information
				/*
				last_returned = read_sos_marker ();
				if (last_returned != SUCCESS)
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: JPEG SOS DECODING ERROR no %d - skipping JPEG\n", last_returned); //this->name(), last_returned);
					initialize();
					end_of_jpeg = true;
				}
				*/
				
				// this flys through the MCU and keep tracks of the current type of 
				// block being processed - for HUffman_thread. This should be 
				// optimised since it is always 4Y+CB+CR- TODO

				if (GetVerbose())
					SpacePrint("EXTR: Start of Scan Marker found... interleaving scan decoding can start\n");

				decode_interleaved_scan ();

				if (GetVerbose())
				{
					SpacePrint("EXTR: End of Scan Marker... waiting for other modules to finish\n");
				}


				// This is the end of the file, we terminate
				
				communicate_IJPEG(SCMD_END_IMAGE);


				
				// reinitialize buffers for jpeg decompression
				initialize();
				
				// we get off this loop and prepare for next image
				end_of_jpeg = true;

                // we launch execution of face detection - 
                // which emulates somne filters to render
                // new images
                launch_face_detection();
				
				computeFor(1);

				break;
				
			//
			// START OF QUANTIZATION TABLE MARKER AT 0xffdb
			//
			case DQT: 		
				
				// ack received with update with memory pointer
				if (read_dqt_marker() != SUCCESS)
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: IQTZ DQT DECODING ERROR no %d - skipping JPEG\n", inmsg.param0); //this->name(), inmsg.param0);
					initialize();
					end_of_jpeg = true;
				}
				break;
				
				
			//
			// START OF IMAGE && END OF IMAGE MARKERS
			//
			case SOI:

				if (GetVerbose())
                   SpacePrint("EXTR: START OF IMAGE marker detected - reading image\n");

				break;
				
			//
			// START OF DEFINE RESTORE INTERVAL TABLE MARKER AT 0xffdb
			//
			/*
			case DRI:
				last_returned = read_dri_marker (); // read info and skip
				if (last_returned != SUCCESS)
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: JPEG DRI DECODING ERROR no %d - skipping JPEG\n", last_returned); //this->name(), last_returned);
					initialize();
					end_of_jpeg = true;
				}
				break;
			*/	
			//
			// END OF IMAGE MARKER - nothing to do
			//
			case MARKER_EOI: // END OF IMAGE MARKER
				break;
				
			//
			// MARKERS WE SKIP
			//
			case APP0:			case APP1:			case APP2:			case APP3:			case APP4:
			case APP5:			case APP6:			case APP7:			case APP8:			case APP9:
			case APP10:			case APP11:			case APP12:			case APP13:			case APP14:
			case APP15:			case COM:			case DRI:
				skip_marker ();				
				break;
				
			//
			// ALL OTHER MARKERS ARE UNSUPPORTED BY THIS APPLICATION
			//
			default: 
				SpacePrint("----------------------------------------\n");
				SpacePrint("EXTRACTOR: JPEG DECODING UNDEFINED MARKER %d - skipping JPEG\n", last_marker); //this->name(), last_marker);
				initialize();
				end_of_jpeg = true;

				break;
			} // switch case
		
		}// while end of jpeg
	
    } // while 1
	
	
	
}
Example #19
0
//////////////////////////////////////////////////////////////////////////////
/// 
/// Transmission of New Image command to IQTZ - wait for acknowledgement before
/// continuing
///
//////////////////////////////////////////////////////////////////////////////
void EXTR::communicate_IJPEG(unsigned short command) {
	JMSG newimage_message;

	switch (command)
	{


	case SCMD_NEW_IMAGE:
		
		if (GetVerbose())
			SpacePrint("EXTR: Sending NEW_IMAGE command to IQTZ - waiting for ACK\n");

		newimage_message.command = SCMD_NEW_IMAGE;
		newimage_message.param1 = m_currentJPEGImageNo;		// current image number
		newimage_message.param0 = m_infoImageHeaderAdd;	// current image info header

		computeFor(1);

		// transmitting request for decompressing new jpeg image - 
		// paramete is address of jpeg iomage to decompress
		ModuleWrite(IQTZ_ID, SPACE_BLOCKING, &newimage_message);
		
		computeFor(1);

		// waiting for acknowledgement with a blocking read
		// parameter is address of decompressed-YUV data
		ModuleRead(IQTZ_ID, SPACE_BLOCKING, &newimage_message);

		computeFor(1);

		if (newimage_message.command == SCMD_NEW_IMAGE_ACK) // collect address of bitmap
		{
			m_decompressedImageAddr[m_currentJPEGImageNo-1] = newimage_message.param0;
            //m_decompressedImageAddr[m_currentJPEGImageNo-1][VALID] = FALSE; // image data not valid while decompressing
		}

		if (GetVerbose())
			SpacePrint("EXTR: Return of ACK from IQTZ imageno:%d; address:%d\n", newimage_message.param0, m_decompressedImageAddr[m_currentJPEGImageNo-1]);

		computeFor(1);
		break;	


	case SCMD_END_IMAGE:
		
		if (GetVerbose())
			SpacePrint("EXTR: END_IMAGE command to send to IQTZ\n");


		newimage_message.command = SCMD_END_IMAGE;
		newimage_message.param1 = m_currentJPEGImageNo;
	
		computeFor(1);

		// transmitting end of request decompressing jpeg image - 
		// this tells the IJPEG module it will receive no more data
		
		ModuleWrite(HUFF_ID, SPACE_BLOCKING, &newimage_message);

		computeFor(1);

		// waiting for acknowledgement with a blocking read
		// parameter is address of decompressed-YUV data
		
		ModuleRead(IQTZ_ID, SPACE_BLOCKING, &newimage_message);
		
		computeFor(1);
		
		if (GetVerbose())
			SpacePrint("EXTR: Return of ACK for END_IMAGE command sent\n");

		break;	
	}
}
Example #20
0
inline UINT16 EXTR::read_16_bits () {
	UINT16 value = (read_8_bits() << 8) | read_8_bits();
	computeFor(1);
	return (value);
}
Example #21
0
//
//  
//////////////////////////////////////////////////////////////////////////////
/// 
/// 
/// Read Start of Frame Marker
///
/// @return =>  UINT16 EXTR::read_sof_marker  : 
///
/// @note   =>  
//////////////////////////////////////////////////////////////////////////////
UINT8 EXTR::read_sof_marker() {
	UINT8 tmp, sof;
	UINT16 frame_header_length;
	UINT8  sample_precision;
	UINT16 number_of_lines, number_of_samples_per_line;
	space_uint2 i, number_of_image_components_in_frame;
	space_uint4 horizontal_sampling_factor, vertical_sampling_factor;
	//UINT16 quantization_table_destination_selector;
	UINT16 horizontal_mcus, vertical_mcus;

	// start_of_image must be detected only once
	if (m_jpeg_decoder_structure.sof_detected == 1)
		return ERROR_SOF_ALREADY_DETECTED;
	m_jpeg_decoder_structure.sof_detected = 1;
	sof = m_jpeg_decoder_structure.sof;
	computeFor(1);

	// 
	frame_header_length = read_16_bits ();

	// sample precision must be baseline = 8
	sample_precision = read_8_bits ();
	if (sample_precision != 8)
	{
		if ((sof == SOF0) || (sample_precision != 12))
			return ERROR_INVALID_SAMPLE_PRECISION;

		return ERROR_TWELVE_BIT_SAMPLE_PRECISION_NOT_SUPPORTED;
	}

	// read # of lines in jpeg
	m_jpeg_decoder_structure.number_of_lines = number_of_lines = 
		read_16_bits ();
	if (number_of_lines == 0)
		return ERROR_ZERO_NUMBER_OF_LINES_NOT_SUPPORTED;
	if (number_of_lines > MAXIMUM_NUMBER_OF_LINES)
		return ERROR_LARGE_NUMBER_OF_LINES_NOT_SUPPORTED;

	// read # of sample per lines in jpeg
	m_jpeg_decoder_structure.number_of_samples_per_line =
		number_of_samples_per_line = read_16_bits ();
	if (number_of_samples_per_line == 0)
		return ERROR_ZERO_SAMPLES_PER_LINE;
	if (number_of_samples_per_line > MAXIMUM_NUMBER_OF_SAMPLES_PER_LINE)
		return ERROR_LARGE_NUMBER_OF_SAMPLES_PER_LINE_NOT_SUPPORTED;
	
	// read # components per frame
	m_jpeg_decoder_structure.number_of_image_components_in_frame =
		number_of_image_components_in_frame = read_8_bits ();
	//if (number_of_image_components_in_frame != 1 &&	number_of_image_components_in_frame != 3)
	if (number_of_image_components_in_frame != 3) // luc: support only 4:2:0
		return ERROR_INVALID_NUMBER_OF_IMAGE_COMPONENTS_IN_FRAME;
	if (frame_header_length != (number_of_image_components_in_frame * 3 + 8))
		return ERROR_INVALID_FRAME_HEADER_LENGTH;

	computeFor(5);

	// for each component in frame
	for (i=0; i<number_of_image_components_in_frame; i++)
	{
		m_jpeg_decoder_structure.component_identifier [i] = read_8_bits ();

		tmp = read_8_bits ();

		// read horizontal & vertical sampling factor
		m_jpeg_decoder_structure.horizontal_sampling_factor [i] = 
			horizontal_sampling_factor = tmp >> 4;
		if (horizontal_sampling_factor == 0 || horizontal_sampling_factor > 4)
			return ERROR_INVALID_HORIZONTAL_SAMPLING_FACTOR;
		m_jpeg_decoder_structure.vertical_sampling_factor [i] = 
			vertical_sampling_factor = tmp & 0xf;
		if (vertical_sampling_factor == 0 || vertical_sampling_factor > 4)
			return ERROR_INVALID_VERTICAL_SAMPLING_FACTOR;

		// read quantization table selector
		//quantization_table_destination_selector = read_8_bits ();
		if (read_8_bits () > 3)
			return ERROR_INVALID_QUANTIZATION_TABLE_DESTINATION_SELECTOR;
			
		computeFor(3);
	}

	// compute the number of effective MCU H + V
	horizontal_mcus = (number_of_samples_per_line + 7) >> 3;
	vertical_mcus = (number_of_lines + 7) >> 3;

	computeFor(3);

	//
	// Fill structure for 4:2:0 image format. Others are rejected
	//
	if ((m_jpeg_decoder_structure . horizontal_sampling_factor [1] == 1) &&
		(m_jpeg_decoder_structure . vertical_sampling_factor [1] == 1) &&
		(m_jpeg_decoder_structure . horizontal_sampling_factor [2] == 1) &&
		(m_jpeg_decoder_structure . vertical_sampling_factor [2] == 1))
	{
		computeFor(1);
		
		if (m_jpeg_decoder_structure . horizontal_sampling_factor [0] == 2)
		{
			horizontal_mcus =	(number_of_samples_per_line + 15) >> 4;

			computeFor(1);

			if (m_jpeg_decoder_structure . vertical_sampling_factor [0] == 2)
			{
				// 4:2:0 format
				m_jpeg_decoder_structure.mcu_size = 384;

				vertical_mcus = (number_of_lines + 15) >> 4;
				
				computeFor(3);
			}