FREObject updateCameraFrame(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { gGrabber.update(); if( !gGrabber.isFrameNew() ) return NULL; FREObject as3Bitmap = argv[0]; FREBitmapData bitmapData; FREAcquireBitmapData(as3Bitmap, &bitmapData); // do something uint32_t r = rand() % 255; uint32_t g = rand() % 255; uint32_t b = rand() % 255; unsigned char *pixel = gGrabber.getPixels(); uint32_t* ptr = bitmapData.bits32; int offset = bitmapData.lineStride32 - bitmapData.width; int alpha = 255; for( uint32_t j = 0; j < bitmapData.height; j++ ){ ptr = bitmapData.bits32 + bitmapData.lineStride32*(bitmapData.height-j-1); for( uint32_t i = 0; i < bitmapData.width; i++ ){ r = *pixel++; g = *pixel++; b = *pixel++; *ptr++ = (alpha << 24) | (r << 16) | (g << 8) | b; } } FREInvalidateBitmapDataRect(as3Bitmap, 0, 0, bitmapData.width, bitmapData.height); FREReleaseBitmapData(as3Bitmap); return NULL; }
FREObject fillBitmapRandomColor(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { FREObject as3Bitmap = argv[0]; FREBitmapData bitmapData; FREAcquireBitmapData(as3Bitmap, &bitmapData); // do something uint32_t r = rand() % 255; uint32_t g = rand() % 255; uint32_t b = rand() % 255; uint32_t* ptr = bitmapData.bits32; int offset = bitmapData.lineStride32 - bitmapData.width; int alpha = 255; for( uint32_t j = 0; j < bitmapData.height; j++ ){ for( uint32_t i = 0; i < bitmapData.width; i++ ){ *ptr++ = (alpha << 24) | (r << 16) | (g << 8) | b; } ptr += offset; } FREInvalidateBitmapDataRect(as3Bitmap, 0, 0, bitmapData.width, bitmapData.height); FREReleaseBitmapData(as3Bitmap); return NULL; }
FREObject __cdecl AmbireCaptureCapture(FREContext ctx, void * functionData, uint32_t argc, FREObject argv[]) { bool success = false; POINT pt = { 0 }; FREBitmapData bd = { 0 }; FREResult result = FREAcquireBitmapData(argv[0], &bd); if(result == FRE_OK) { int width = bd.width; int height = bd.height; BITMAPINFOHEADER bmi = { 0 }; bmi.biSize = sizeof(bmi); bmi.biWidth = width; bmi.biHeight = height; bmi.biPlanes = 1; bmi.biBitCount = 24; int stride = ((width * 3 + 3) / 4) * 4; bmi.biSizeImage = stride * height; void * ppvBits = 0; HDC hdcDesktop = GetDC(0); if(hdcDesktop) { HDC hdcMem = CreateCompatibleDC(hdcDesktop); if(hdcMem) { HBITMAP hbm = CreateDIBSection(hdcMem, (const BITMAPINFO *)&bmi, 0, &ppvBits, 0, 0); if(hbm) { SelectObject(hdcMem, hbm); BitBlt(hdcMem, 0, 0, width, height, hdcDesktop, 0, 0, SRCCOPY); GdiFlush(); ReleaseDC(0, hdcDesktop); DeleteDC(hdcMem); GdiFlush(); for(int y = 0; y < height; ++y) { const unsigned char * p = reinterpret_cast<unsigned char *>(ppvBits) + y * stride; uint32_t * q = reinterpret_cast<uint32_t *>(bd.bits32) + y * bd.lineStride32; for(int x = 0; x < width; ++x, p += 3, ++q) { *q = 0xFF000000 | (p[2] << 16) | (p[1] << 8) | p[0]; } } success = true; DeleteObject(hbm); } else { DeleteDC(hdcMem); } } else { ReleaseDC(0, hdcDesktop); } } FREReleaseBitmapData(argv[0]); } FREObject rv = 0; FRENewObjectFromBool(success ? 1 : 0, &rv); return rv; }
FREObject getCaptureFrame(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { int32_t _id, _opt; FREGetObjectAsInt32(argv[0], &_id); FREObject res_obj; FRENewObjectFromInt32(0, &res_obj); FREObject objectBA; FREByteArray baData; FREBitmapData2 bitmapData; uint8_t *ba; const uint8_t* frame_0; const uint8_t* frame; int32_t w, h, w2, h2, widthInBytes, i, j; uint32_t fstride; CCapture* cap; cap = active_cams[_id]; uint32_t flipped = 0; uint32_t isWin = 1; #if defined(ANE_MAC) isWin = 0; #endif objectBA = argv[1]; FREAcquireByteArray(objectBA, &baData); ba = baData.bytes; ba += ba_read_int(ba, &_opt); ba += ba_read_int(ba, &w2); ba += ba_read_int(ba, &h2); FREReleaseByteArray(objectBA); if(cap && captureCheckNewFrame(cap)) { frame_0 = (const uint8_t*)captureGetFrame(cap, &w, &h, &widthInBytes); // here is some conversion we need cause in Flash BitmapData bytes // represented differently :( if((_opt & FRAME_BITMAP)) { objectBA = argv[2]; FREAcquireBitmapData2(objectBA, &bitmapData); uint32_t* input = bitmapData.bits32; fstride = bitmapData.lineStride32 * sizeof(uint32_t); // for some reasons not always == width flipped = bitmapData.isInvertedY; frame = frame_0; ba = (uint8_t*)input; #if defined (__ANDROID__) || defined (ANE_IOS) for(i=0; i<h; i++){ memcpy(ba+i*fstride, frame+i*widthInBytes, fstride); } #else // most likely wont happen / but who knows? ;) if(flipped && !isWin) { const uint8_t* a_ptr = (const uint8_t*)frame; const uint8_t* a_ptr2 = (const uint8_t*)(frame + (h - 1) * widthInBytes); uint8_t* b_ptr = ba + (h - 1) * fstride; uint8_t* b_ptr2 = ba; for(i = 0; i < h / 2; i++) { uint8_t *ba_ln = b_ptr; uint8_t *ba_ln2 = b_ptr2; const uint8_t *a_ln = a_ptr; const uint8_t *a_ln2 = a_ptr2; #if defined(ANE_MSW) for(j = 0; j < w; j++, ba_ln += 4, ba_ln2 += 4, a_ln += 3, a_ln2 += 3) { *ba_ln = *(a_ln); ba_ln[1] = *(a_ln+1); ba_ln[2] = *(a_ln+2); // *ba_ln2 = *(a_ln2); ba_ln2[1] = *(a_ln2+1); ba_ln2[2] = *(a_ln2+2); } #elif defined(ANE_MAC) memcpy(ba_ln, a_ln, widthInBytes); memcpy(ba_ln2, a_ln2, widthInBytes); #endif a_ptr += widthInBytes; a_ptr2 -= widthInBytes; b_ptr -= fstride; b_ptr2 += fstride; } if(h&1) { #if defined(ANE_MSW) for(j = 0; j < w; j++, b_ptr += 4, a_ptr+=3) { *b_ptr = *(a_ptr); b_ptr[1] = *(a_ptr+1); b_ptr[2] = *(a_ptr+2); } #elif defined(ANE_MAC) memcpy(b_ptr, a_ptr, widthInBytes); #endif } } else { for(i = 0; i < h; i++) { uint8_t *ba_ln = ba; const uint8_t *fr_ln = frame; #if defined(ANE_MSW) for(j = 0; j < w; j++, ba_ln += 4, fr_ln += 3) { *ba_ln = *(fr_ln); ba_ln[1] = *(fr_ln+1); ba_ln[2] = *(fr_ln+2); } #elif defined(ANE_MAC) memcpy(ba_ln, fr_ln, widthInBytes); #endif ba += fstride; frame += widthInBytes; } } #endif FREReleaseBitmapData(objectBA); } if((_opt & FRAME_RAW)) { objectBA = argv[3]; FREAcquireByteArray(objectBA, &baData); ba = baData.bytes; memcpy(ba, frame_0, widthInBytes * h); FREReleaseByteArray(objectBA); } // power of 2 output for stage3d if((_opt & FRAME_P2_BGRA)) { objectBA = argv[4]; FREAcquireByteArray(objectBA, &baData); ba = baData.bytes; frame = frame_0; // resize /* if(w > w2 || h > h2) { float scx = (float)w2 / (float)w; float scy = (float)h2 / (float)h; if(scy < scx) scx = scy; int32_t wr = w * scx; int32_t hr = h * scx; uint8_t *frame_rs = allocResizeBuf(wr, hr, 4); //resample_area_8u(frame, w, h, frame_rs, wr, hr, 4); // update values w = wr; h = hr; frame = frame_rs; widthInBytes = wr * sizeof(uint32_t); } */ int32_t p2w = (w2); int32_t p2h = (h2); int32_t off_x = (p2w - w) / 2; // -64 int32_t off_y = (p2h - h) / 2; size_t p2stride = p2w * sizeof(uint32_t); int32_t b_off_x, b_off_y, a_off_x, a_off_y; if(off_x < 0) { b_off_x = 0; a_off_x = -off_x; } else { b_off_x = off_x; a_off_x = 0; } if(off_y < 0) { b_off_y = 0; a_off_y = -off_y; } else { b_off_y = off_y; a_off_y = 0; } uint8_t* b_ptr0 = ba + b_off_y * p2stride + b_off_x*4; int32_t nw = w - a_off_x*2; int32_t nh = h - a_off_y*2; #if defined (ANE_MSW) // we need flip Y const uint8_t* a_ptr0 = (const uint8_t*)(frame + a_off_y * widthInBytes + a_off_x*3); const uint8_t* a_ptr = a_ptr0; const uint8_t* a_ptr2 = a_ptr0 + (nh - 1) * widthInBytes; uint8_t* b_ptr = b_ptr0 + (h - 1) * p2stride; uint8_t* b_ptr2 = b_ptr0; const uint8_t alpha = 0xFF; for(i = 0; i < nh / 2; i++) { uint8_t *ba_ln = b_ptr; uint8_t *ba_ln2 = b_ptr2; const uint8_t *a_ln = a_ptr; const uint8_t *a_ln2 = a_ptr2; for(j = 0; j < nw; j++, ba_ln += 4, ba_ln2 += 4, a_ln += 3, a_ln2 += 3) { *ba_ln = *(a_ln+0); ba_ln[1] = *(a_ln+1); ba_ln[2] = *(a_ln+2); ba_ln[3] = alpha; // *ba_ln2 = *(a_ln2+0); ba_ln2[1] = *(a_ln2+1); ba_ln2[2] = *(a_ln2+2); ba_ln2[3] = alpha; } a_ptr += widthInBytes; a_ptr2 -= widthInBytes; b_ptr -= p2stride; b_ptr2 += p2stride; } if(nh&1) { for(j = 0; j < nw; j++, b_ptr += 4, a_ptr+=3) { *b_ptr = *(a_ptr+0); b_ptr[1] = *(a_ptr+1); b_ptr[2] = *(a_ptr+2); b_ptr[3] = alpha; } } #elif defined(ANE_MAC) || defined (ANE_IOS) || defined (__ANDROID__) const uint8_t* a_ptr0 = (const uint8_t*)(frame + a_off_y * widthInBytes + a_off_x*4); for(i = 0; i < nh; i++) { memcpy(b_ptr0, a_ptr0, nw*4); a_ptr0 += widthInBytes; b_ptr0 += p2stride; } #endif FREReleaseByteArray(objectBA); } FRENewObjectFromInt32(1, &res_obj); } else if(cap) { // lets see if device is available it may be freezed if( captureCheckResponse(cap) == 0 ) { FRENewObjectFromInt32(-1, &res_obj); } } return res_obj; }