static PassRefPtr<Evas_Object> readImageFromStdin(Evas* evas, long imageSize) { OwnArrayPtr<unsigned char> imageBuffer = adoptArrayPtr(new unsigned char[imageSize]); if (!imageBuffer) abortWithErrorMessage("cannot allocate image"); const size_t bytesRead = fread(imageBuffer.get(), 1, imageSize, stdin); if (!bytesRead) return PassRefPtr<Evas_Object>(); Evas_Object* image = evas_object_image_filled_add(evas); evas_object_image_colorspace_set(image, EVAS_COLORSPACE_ARGB8888); evas_object_image_memfile_set(image, imageBuffer.get(), bytesRead, 0, 0); resizeEcoreEvasIfNeeded(image); return adoptRef(image); }
void CalaosCameraView::requestCompleted() { if (single_frame) { evas_object_image_memfile_set(camImage, &buffer[0], buffer.size(), NULL, NULL); Evas_Load_Error err = evas_object_image_load_error_get(camImage); if (err != EVAS_LOAD_ERROR_NONE) cErrorDom("camera") << "could not load image. error string is \"%s\"" << evas_load_error_str(err); } if (format_error) return; EcoreTimer::singleShot(0, [=]() { if (!single_frame) cWarningDom("camera") << "Restarting request to camera..."; play(); }); }
void CalaosCameraView::processData() { if (!formatDetected) { //first frame, we need to look for the boundary //and for content-type/content-length if present if (buffer.size() < 4) return; //need more data if (buffer[0] != '-' || buffer[1] != '-') { //try to detect of the data is directly the jpeg picture if (buffer[0] == 0xFF && buffer[1] == 0xD8) { cWarningDom("camera") << "Data seems to be a single frame."; single_frame = true; } else { cWarningDom("camera") << "Wrong start of frame, give up!"; format_error = true; } formatDetected = true; return; } //search for the line end after the boundary to get the boundary text int end, next; if (!readEnd(2, end, next)) { if (buffer.size() > 500) { cWarningDom("camera") << "Boundary not found, give up!"; format_error = true; } return; //need more data; } //get boundary boundary = string((char *)&buffer[0], end); cDebugDom("camera") << "Found boundary \"" << boundary << "\""; int i = next; while (readEnd(next, end, next)) { int len = end - i; if (len == 0) { //line is empty, data starts now nextDataStart = next; formatDetected = true; scanpos = 0; break; } if (len > 15) { string s((char *)&buffer[i], len); if (Utils::strStartsWith(s, "Content-Length", Utils::CaseInsensitive)) { Utils::from_string(s.substr(15), nextContentLength); cDebugDom("camera") << "Found content length header: \"" << nextContentLength << "\""; //nextContentLength = -1; //to test code without content-length header } } i = next; } if (!formatDetected) { cWarningDom("camera") << "need more data..."; return; } } if (formatDetected && !single_frame) { //we should be positionned at the start of data //small check to be sure if (buffer.size() <= nextDataStart) { cWarningDom("camera") << "need more data..."; return; } if (!(buffer[nextDataStart] == 0xFF && buffer[nextDataStart + 1] == 0xD8)) { cWarningDom("camera") << "Wrong image data."; format_error = true; EcoreTimer::singleShot(0, [=]() { cDebugDom("camera") << "Cancel stream"; ecore_con_url_free(ecurl); ecurl = nullptr; }); return; } if (nextContentLength >= 0) { //the content-length is known, fast path if ((int)buffer.size() < nextContentLength + nextDataStart + 2) return; //need more data cDebugDom("camera") << "Set new frame"; evas_object_image_memfile_set(camImage, &buffer[nextDataStart], nextContentLength, NULL, NULL); //evas_object_image_size_get(camImage, &w, &h); if (buffer[nextDataStart + nextContentLength] == '\r') //assume a \n always follows \r nextContentLength += 2; else if (buffer[nextDataStart + nextContentLength] == '\n') nextContentLength += 1; //remove unused data from buffer auto iter = buffer.begin(); buffer.erase(iter, iter + (nextDataStart + nextContentLength)); //reset for next frame nextContentLength = -1; formatDetected = false; nextDataStart = 0; scanpos = 0; } else { uint i = 0; cDebugDom("camera") << "scanpos: " << scanpos; for (i = nextDataStart + scanpos; i < buffer.size() - boundary.length();i++) { if (buffer[i] == '-' && buffer[i + 1] == '-' && !boundary.compare(0, boundary.length(), (const char *)&buffer[i], boundary.length())) { //boundary found //check for newline between boundary and data nextContentLength = i - nextDataStart; if (buffer[i - 2] == '\r') nextContentLength -= 2; else if (buffer[i - 1] == '\n') nextContentLength -= 1; evas_object_image_memfile_set(camImage, &buffer[nextDataStart], nextContentLength, NULL, NULL); //evas_object_image_size_get(camImage, &w, &h); if (buffer[nextDataStart + nextContentLength] == '\r') //assume a \n always follows \r nextContentLength += 2; else if (buffer[nextDataStart + nextContentLength] == '\n') nextContentLength += 1; //remove unused data from buffer auto iter = buffer.begin(); buffer.erase(iter, iter + (nextDataStart + nextContentLength)); //reset for next frame nextContentLength = -1; formatDetected = false; nextDataStart = 0; scanpos = 0; cDebugDom("camera") << "scanpos: " << scanpos << " --> return"; return; } } scanpos = i - nextDataStart; cDebugDom("camera") << "--> scanpos: " << scanpos; } } }