/****************************************** * write the alert message to the alert socket ******************************************/ int AlertSocketAction(int RuleNum, int PacketSlot, void* Data){ char Buff[1024]; ActionSocketRec* data; PacketRec* p; DEBUGPATH; if (!Data){ #ifdef DEBUG printf("I must have a socket to write to\n"); #endif return FALSE; } p=&Globals.Packets[PacketSlot]; data=(ActionSocketRec*)Data; if (data->Retries>MAX_SOCKET_RETRIES) return FALSE; if (!ApplyMessage(Globals.AlertHeader, PacketSlot, Buff, 1024)){ printf("Couldn't alert header to packet\n"); return FALSE; } if (write(data->SockFD, Buff, strlen(Buff))==-1){ if (AlertSocketConnect(data)) write(data->SockFD, Buff, strlen(Buff)); } if (write(data->SockFD, " ", 1)==-1){ if (AlertSocketConnect(data)) write(data->SockFD, " ", 1); } if (!ApplyMessage(Globals.Rules[RuleNum].MessageFormat, PacketSlot, Buff, 1024)){ printf("Couldn't apply message to packet\n"); return FALSE; } if (write(data->SockFD, Buff, strlen(Buff))==-1){ if (AlertSocketConnect(data)) write(data->SockFD, Buff, strlen(Buff)); } if (write(data->SockFD, "\n", 1)==-1){ if (AlertSocketConnect(data)) write(data->SockFD, "\n", 1); } return TRUE; }
bool ImageReader::checkProperties(ifstream & file, PVideoFrame & frame, IScriptEnvironment * env) { if (!file.is_open()) { if (info) ApplyMessage(&frame, vi, "ImageReader: cannot open file", vi.width/4, TEXT_COLOR,0,0 , env); return false; } BITMAPFILEHEADER tempFileHeader; BITMAPINFOHEADER tempInfoHeader; file.read( reinterpret_cast<char *> (&tempFileHeader), sizeof(tempFileHeader) ); file.read( reinterpret_cast<char *> (&tempInfoHeader), sizeof(tempInfoHeader) ); if (tempFileHeader.bfType != fileHeader.bfType) { ApplyMessage(&frame, vi, "ImageReader: invalid (E)BMP file", vi.width/4, TEXT_COLOR,0,0 , env); return false; } if (tempInfoHeader.biWidth != infoHeader.biWidth) { ApplyMessage(&frame, vi, "ImageReader: image widths must be identical", vi.width/4, TEXT_COLOR,0,0 , env); return false; } if (tempInfoHeader.biHeight != infoHeader.biHeight) { ApplyMessage(&frame, vi, "ImageReader: image heights must be identical", vi.width/4, TEXT_COLOR,0,0 , env); return false; } if (tempInfoHeader.biPlanes != infoHeader.biPlanes) { ApplyMessage(&frame, vi, "ImageReader: images must have the same number of planes", vi.width/4, TEXT_COLOR,0,0 , env); return false; } if (tempInfoHeader.biBitCount != infoHeader.biBitCount) { ApplyMessage(&frame, vi, "ImageReader: images must have identical bits per pixel", vi.width/4, TEXT_COLOR,0,0 , env); return false; } if (tempFileHeader.bfSize != fileHeader.bfSize) { ApplyMessage(&frame, vi, "ImageReader: raster sizes must be identical", vi.width/4, TEXT_COLOR,0,0 , env); return false; } if (tempInfoHeader.biCompression != 0) { ApplyMessage(&frame, vi, "ImageReader: EBMP reader cannot handle compressed images", vi.width/4, TEXT_COLOR,0,0 , env); return false; } return true; }
/* Write the alert message to syslog */ int AlertSyslogAction(int RuleNum, int PacketSlot, void *Data) { char Buff[1024]; PacketRec *p; ActionSyslogRec *data; DEBUGPATH; DBG((printf("Sending alert to syslog\n"))); if (!Data) { DBG((printf("FAILED: %s(%p)\n", __FUNCTION__, Data))); return FALSE; } data = (ActionSyslogRec *) Data; if (data->Active != TRUE) SyslogInit(data); p = &Globals.Packets[PacketSlot]; if (!ApplyMessage (Globals.Rules[RuleNum].MessageFormat, PacketSlot, Buff, 1024)) { printf("Couldn't apply message to packet for syslog\n"); return FALSE; } syslog(data->priority, "%s", ((Buff != NULL) ? Buff : "ALERT!")); return TRUE; }
PVideoFrame __stdcall ConditionalReader::GetFrame(int n, IScriptEnvironment* env) { AVSValue v = GetFrameValue(n); env->SetGlobalVar(variableName, v); PVideoFrame src = child->GetFrame(n,env); if (show) { AVSValue v2 = env->Invoke("String", v); env->MakeWritable(&src); ApplyMessage(&src, vi, v2.AsString(""), vi.width/2, 0xa0a0a0,0,0 , env ); } return src; }
PVideoFrame __stdcall ScriptClip::GetFrame(int n, IScriptEnvironment* env) { AVSValue prev_last = env->GetVar("last"); // Store previous last AVSValue prev_current_frame = GetVar(env, "current_frame"); // Store previous current_frame env->SetVar("last",(AVSValue)child); // Set explicit last env->SetVar("current_frame",(AVSValue)n); // Set frame to be tested by the conditional filters. if (show) { PVideoFrame dst = child->GetFrame(n,env); env->MakeWritable(&dst); ApplyMessage(&dst, vi, script.AsString(), vi.width/6, 0xa0a0a0,0,0 , env ); env->SetVar("last",prev_last); // Restore implicit last env->SetVar("current_frame",prev_current_frame); // Restore current_frame return dst; } AVSValue result; PVideoFrame eval_return; // Frame to be returned if script should be evaluated AFTER frame has been fetched. Otherwise not used. if (eval_after) eval_return = child->GetFrame(n,env); try { ScriptParser parser(env, script.AsString(), "[ScriptClip]"); PExpression exp = parser.Parse(); result = exp->Evaluate(env); } catch (AvisynthError error) { const char* error_msg = error.msg; PVideoFrame dst = child->GetFrame(n,env); env->MakeWritable(&dst); ApplyMessage(&dst, vi, error_msg, vi.width/W_DIVISOR, 0xa0a0a0,0,0 , env ); env->SetVar("last",prev_last); // Restore implicit last env->SetVar("current_frame",prev_current_frame); // Restore current_frame return dst; } env->SetVar("last",prev_last); // Restore implicit last env->SetVar("current_frame",prev_current_frame); // Restore current_frame if (eval_after && only_eval) return eval_return; if (only_eval) return child->GetFrame(n,env); const char* error = NULL; VideoInfo vi2; if (!result.IsClip()) { error = "ScriptClip: Function did not return a video clip!"; } else { vi2 = result.AsClip()->GetVideoInfo(); if (!vi.IsSameColorspace(vi2)) { error = "ScriptClip: Function did not return a video clip of the same colorspace as the source clip!"; } else if (vi2.width != vi.width) { error = "ScriptClip: Function did not return a video clip with the same width as the source clip!"; } else if (vi2.height != vi.height) { error = "ScriptClip: Function did not return a video clip with the same height as the source clip!"; } } if (error != NULL) { PVideoFrame dst = child->GetFrame(n,env); env->MakeWritable(&dst); ApplyMessage(&dst, vi, error, vi.width/W_DIVISOR, 0xa0a0a0,0,0 , env ); return dst; } n = min(n,vi2.num_frames-1); // We ignore it if the new clip is not as long as the current one. This can allow the resulting clip to be one frame. return result.AsClip()->GetFrame(n,env); }
PVideoFrame __stdcall ConditionalFilter::GetFrame(int n, IScriptEnvironment* env) { VideoInfo vi1 = source1->GetVideoInfo(); VideoInfo vi2 = source2->GetVideoInfo(); AVSValue prev_last = env->GetVar("last"); // Store previous last AVSValue prev_current_frame = GetVar(env, "current_frame"); // Store previous current_frame env->SetVar("last",(AVSValue)child); // Set implicit last env->SetVar("current_frame",(AVSValue)n); // Set frame to be tested by the conditional filters. AVSValue e1_result; AVSValue e2_result; try { ScriptParser parser(env, eval1.AsString(), "[Conditional Filter, Expresion 1]"); PExpression exp = parser.Parse(); e1_result = exp->Evaluate(env); ScriptParser parser2(env, eval2.AsString(), "[Conditional Filter, Expression 2]"); exp = parser2.Parse(); e2_result = exp->Evaluate(env); } catch (AvisynthError error) { const char* error_msg = error.msg; PVideoFrame dst = source1->GetFrame(n,env); env->MakeWritable(&dst); ApplyMessage(&dst, vi1, error_msg, vi.width/W_DIVISOR, 0xa0a0a0,0,0 , env ); env->SetVar("last",prev_last); // Restore implicit last env->SetVar("current_frame",prev_current_frame); // Restore current_frame return dst; } env->SetVar("last",prev_last); // Restore implicit last env->SetVar("current_frame",prev_current_frame); // Restore current_frame int test_int=false; int e1 = 0; int e2 = 0; float f1 = 0.0f; float f2 = 0.0f; try { if (e1_result.IsInt() || e1_result.IsBool()) { test_int = true; e1 = e1_result.IsInt() ? e1_result.AsInt() : e1_result.AsBool(); if (!(e2_result.IsInt() || e2_result.IsBool())) env->ThrowError("Conditional filter: Second expression did not return an integer or bool, as first expression."); e2 = e2_result.IsInt() ? e2_result.AsInt() : e2_result.AsBool(); } else if (e1_result.IsFloat()) { f1 = e1_result.AsFloat(); if (!e2_result.IsFloat()) env->ThrowError("Conditional filter: Second expression did not return a float or an integer, as first expression."); f2 = e2_result.AsFloat(); } else { env->ThrowError("ConditionalFilter: First condition did not return an int, bool or float!"); } } catch (AvisynthError error) { const char* error_msg = error.msg; PVideoFrame dst = source1->GetFrame(n,env); env->MakeWritable(&dst); ApplyMessage(&dst, vi1, error_msg, vi.width/W_DIVISOR, 0xa0a0a0,0,0 , env ); return dst; } bool state = false; if (test_int) { if (evaluator&EQUALS) if (e1 == e2) state = true; if (evaluator&GREATERTHAN) if (e1 > e2) state = true; if (evaluator&LESSTHAN) if (e1 < e2) state = true; } else { // Float compare if (evaluator&EQUALS) if (fabs(f1-f2)<0.000001f) state = true; // Exact equal will sometimes be rounded to wrong values. if (evaluator&GREATERTHAN) if (f1 > f2) state = true; if (evaluator&LESSTHAN) if (f1 < f2) state = true; } if (show) { char text[400]; if (test_int) { sprintf(text, "Left side Conditional Result:%i\n" "Right side Conditional Result:%i\n" "Evaluate result: %s\n", e1, e2, (state) ? t_TRUE : t_FALSE ); } else { sprintf(text, "Left side Conditional Result:%7.4f\n" "Right side Conditional Result:%7.4f\n" "Evaluate result: %s\n", f1, f2, (state) ? t_TRUE : t_FALSE ); } PVideoFrame dst = (state) ? source1->GetFrame(min(vi1.num_frames-1,n),env) : source2->GetFrame(min(vi2.num_frames-1,n),env); env->MakeWritable(&dst); ApplyMessage(&dst, vi, text, vi.width/4, 0xa0a0a0,0,0 , env ); return dst; } if (state) return source1->GetFrame(min(vi1.num_frames-1,n),env); return source2->GetFrame(min(vi1.num_frames-1,n),env); }
/** \fn getNextFrame */ bool vidColorYuv::getNextFrame(uint32_t *fn,ADMImage *image) { //x PVideoFrame src; //x unsigned long *srcp; uint8_t *srcp; int pitch, w, h; int i,j,wby4; int modulo; #if 0 //ifdef _DEBUG COUNT y0,u0,v0; COUNT y,u,v; COUNT r,g,b; COUNT r0,g0,b0; PIXELDATA pixel0; int total,totalby2; #endif #if 0 if (colorbars) { PVideoFrame dst= env->NewVideoFrame(vi); int* pdst=(int*)dst->GetWritePtr(PLANAR_Y); int Y=16+abs(219-((frame+219)%438)); Y|=(Y<<8)|(Y<<16)|(Y<<24); for (int i = 0;i<224*224;i++) pdst[i] = Y; unsigned char* pdstb = dst->GetWritePtr(PLANAR_U); for (unsigned int y=0;y<224;y++) { for (unsigned int x=0;x<224;x++) { pdstb[x] = 16+x; } pdstb += dst->GetPitch(PLANAR_U); } pdstb = dst->GetWritePtr(PLANAR_V); for (y=0;y<224;y++) { for (unsigned int x=0;x<224;x++) { pdstb[x] = 16+y; } pdstb += dst->GetPitch(PLANAR_U); } return dst; } #endif if(false==previousFilter->getNextFrame(fn,image)) { return false; } ADMImage *src=image; //x src = child->GetFrame(frame, env); //x env->MakeWritable(&src); //x srcp = (unsigned long *) src->GetWritePtr(); //x pitch = src->GetPitch(); srcp=src->GetWritePtr(PLANAR_Y); pitch=src->GetPitch(PLANAR_Y); w = info.width; //x src->GetRowSize(); h = info.height; //x src->GetHeight(); wby4 = w / 4; modulo = pitch - w; // dst = env->NewVideoFrame(vi); // dstp = (unsigned long *) dst->GetWritePtr(); // dpitch = dst->GetPitch(); // dmodulo = dpitch - dst->GetRowSize(); if (param.analyze||param.autowhite||param.autogain) { unsigned int accum_Y[256],accum_U[256],accum_V[256]; for (int i=0;i<256;i++) { accum_Y[i]=0; accum_U[i]=0; accum_V[i]=0; } int uvdiv=1; //UV divider (ratio between Y and UV pixels) if (1) { //x vi.IsPlanar()) { uvdiv=4; BYTE* srcp2 = (BYTE*) src->GetReadPtr(PLANAR_Y); for (int y=0;y<h;y++) { for (int x=0;x<w;x++) { accum_Y[srcp2[x]]++; } srcp2+=pitch; } pitch = src->GetPitch(PLANAR_U); srcp2 = (BYTE*) src->GetReadPtr(PLANAR_U); for (int y=0;y<h/2;y++) { for (int x=0;x<w/2;x++) { accum_U[srcp2[x]]++; } srcp2+=pitch; } srcp2 = (BYTE*) src->GetReadPtr(PLANAR_V); for (int y=0;y<h/2;y++) { for (int x=0;x<w/2;x++) { accum_V[srcp2[x]]++; } srcp2+=pitch; } pitch = src->GetPitch(PLANAR_Y); } #if 0 else { // YUY2 uvdiv=2; for (int y=0;y<h;y++) { for (int x=0;x<wby4;x++) { unsigned long p=srcp[x]; accum_Y[p&0xff]++; accum_Y[(p>>16)&0xff]++; accum_U[(p>>8)&0xff]++; accum_V[(p>>24)&0xff]++; } srcp+=pitch/4; } srcp=(unsigned long *)src->GetReadPtr(); } #endif int pixels = info.width*info.height; float avg_u=0, avg_v=0, avg_y=0; int x_min_u=0, x_min_v=0, x_min_y=0; int x_max_u=0, x_max_v=0, x_max_y=0; bool hit_y=false,hit_u=false,hit_v=false; int Ax_min_u=0, Ax_min_v=0, Ax_min_y=0; int Ax_max_u=0, Ax_max_v=0, Ax_max_y=0; bool Ahit_x_miny=false,Ahit_x_minu=false,Ahit_x_minv=false; bool Ahit_x_maxy=false,Ahit_x_maxu=false,Ahit_x_maxv=false; int At_y2=(pixels/256); // When 1/256th of all pixels have been reached, trigger "Loose x_min/x_max" int At_uv2=(pixels/1024); for (int i=0;i<256;i++) { avg_y+=(float)accum_Y[i]*(float)i; avg_u+=(float)accum_U[i]*(float)i; avg_v+=(float)accum_V[i]*(float)i; if (accum_Y[i]!=0) {x_max_y=i;hit_y=true;} else {if (!hit_y) x_min_y=i+1;} if (accum_U[i]!=0) {x_max_u=i;hit_u=true;} else {if (!hit_u) x_min_u=i+1;} if (accum_V[i]!=0) {x_max_v=i;hit_v=true;} else {if (!hit_v) x_min_v=i+1;} if (!Ahit_x_miny) {Ax_min_y+=accum_Y[i]; if (Ax_min_y>At_y2){Ahit_x_miny=true; Ax_min_y=i;} } if (!Ahit_x_minu) {Ax_min_u+=accum_U[i]; if (Ax_min_u>At_uv2){Ahit_x_minu=true; Ax_min_u=i;} } if (!Ahit_x_minv) {Ax_min_v+=accum_V[i]; if (Ax_min_v>At_uv2){Ahit_x_minv=true; Ax_min_v=i;} } if (!Ahit_x_maxy) {Ax_max_y+=accum_Y[255-i]; if (Ax_max_y>At_y2){Ahit_x_maxy=true; Ax_max_y=255-i;} } if (!Ahit_x_maxu) {Ax_max_u+=accum_U[255-i]; if (Ax_max_u>At_uv2){Ahit_x_maxu=true; Ax_max_u=255-i;} } if (!Ahit_x_maxv) {Ax_max_v+=accum_V[255-i]; if (Ax_max_v>At_uv2){Ahit_x_maxv=true; Ax_max_v=255-i;} } } float Favg_y=avg_y/(float)pixels; float Favg_u=(avg_u*(float)uvdiv)/(float)pixels; float Favg_v=(avg_v*(float)uvdiv)/(float)pixels; if (param.analyze) { #if 0 char text[400]; sprintf(text, " Frame: %-8u ( Luma Y / ChromaU / ChromaV )\n" " Average: ( %7.2f / %7.2f / %7.2f )\n" " x_minimum: ( %3d / %3d / %3d )\n" " x_maximum: ( %3d / %3d / %3d )\n" "Loose x_minimum: ( %3d / %3d / %3d )\n" "Loose x_maximum: ( %3d / %3d / %3d )\n" , frame, Favg_y,Favg_u,Favg_v, x_min_y,x_min_u,x_min_v, x_max_y,x_max_u,x_max_v, Ax_min_y,Ax_min_u,Ax_min_v, Ax_max_y,Ax_max_u,Ax_max_v ); ApplyMessage(&src, vi, text, vi.width/4, 0xa0a0a0,0,0 , env ); if (!(param.autowhite||param.autogain)) { return true; //x src; } #endif } if (param.autowhite) { param.u_bright=127-(int)Favg_u; param.v_bright=127-(int)Favg_v; } if (param.autogain) { Ax_max_y=x_min(Ax_max_y,236); Ax_min_y=x_max(Ax_min_y,16); // Never scale above luma range! if (Ax_min_y!=Ax_max_y) { int y_range = Ax_max_y-Ax_min_y; double scale = (220.0 / y_range); param.y_gain = (int) (256.0 * scale)-256; param.y_bright = -(int)(scale * (double)(Ax_min_y)-16); } } MakeGammaLUT(); }
PVideoFrame ImageReader::GetFrame(int n, IScriptEnvironment* env) { ILenum err = IL_NO_ERROR; PVideoFrame frame = env->NewVideoFrame(vi); BYTE * dstPtr = frame->GetWritePtr(); BYTE * const WritePtr = dstPtr; const int pitch = frame->GetPitch(); const int row_size = frame->GetRowSize(); const int height = frame->GetHeight(); const int width = vi.width; _snprintf(filename, sizeof filename, base_name, n+start); if (use_DevIL) /* read using DevIL */ { // Setup ILuint myImage=0; ilGenImages(1, &myImage); ilBindImage(myImage); if (ilLoadImage(filename) == IL_FALSE) { // Get errors if any err = ilGetError(); // Cleanup ilDeleteImages(1, &myImage); memset(WritePtr, 0, pitch * height); // Black frame if ((info) || (err != IL_COULD_NOT_OPEN_FILE)) { ostringstream ss; ss << "ImageReader: error '" << getErrStr(err) << "' in DevIL library\n opening file \"" << filename << "\""; ApplyMessage(&frame, vi, ss.str().c_str(), vi.width/4, TEXT_COLOR,0,0 , env); } return frame; } // Check some parameters if ( ilGetInteger(IL_IMAGE_HEIGHT) != height) { // Cleanup ilDeleteImages(1, &myImage); memset(WritePtr, 0, pitch * height); ApplyMessage(&frame, vi, "ImageReader: images must have identical heights", vi.width/4, TEXT_COLOR,0,0 , env); return frame; } if ( ilGetInteger(IL_IMAGE_WIDTH) != width) { // Cleanup ilDeleteImages(1, &myImage); memset(WritePtr, 0, pitch * height); ApplyMessage(&frame, vi, "ImageReader: images must have identical widths", vi.width/4, TEXT_COLOR,0,0 , env); return frame; } const ILenum il_format = vi.IsRGB32() ? IL_BGRA : IL_BGR; const ILenum linesize = width * (vi.IsRGB32() ? 4 : 3); // Copy raster to AVS frame ////if (ilGetInteger(IL_ORIGIN_MODE) == IL_ORIGIN_UPPER_LEFT, IL_ORIGIN_LOWER_LEFT ??? if (should_flip) { // Copy upside down for (int y=height-1; y>=0; --y) { if (ilCopyPixels(0, y, 0, width, 1, 1, il_format, IL_UNSIGNED_BYTE, dstPtr) > linesize) break; // Try not to spew all over memory dstPtr += pitch; } } else { // Copy right side up for (int y=0; y<height; ++y) { if (ilCopyPixels(0, y, 0, width, 1, 1, il_format, IL_UNSIGNED_BYTE, dstPtr) > linesize) break; // Try not to spew all over memory dstPtr += pitch; } } // Get errors if any err = ilGetError(); // Cleanup ilDeleteImages(1, &myImage); if (err != IL_NO_ERROR) { memset(WritePtr, 0, pitch * height); ostringstream ss; ss << "ImageReader: error '" << getErrStr(err) << "' in DevIL library\n reading file \"" << filename << "\""; ApplyMessage(&frame, vi, ss.str().c_str(), vi.width/4, TEXT_COLOR,0,0 , env); return frame; } } else { /* treat as ebmp */ // Open file, ensure it has the expected properties ifstream file(filename, ios::binary); if (!checkProperties(file, frame, env)) { file.close(); return frame; } // Seek past padding file.seekg (fileHeader.bfOffBits, ios::beg); // Read in raster if (0) // (vi.IsY8()) { // read upside down BYTE * endPtr = dstPtr + pitch * (height-1); fileRead(file, endPtr, -pitch, row_size, height); } else { fileRead(file, dstPtr, pitch, row_size, height); if (vi.IsPlanar()) { dstPtr = frame->GetWritePtr(PLANAR_U); const int pitchUV = frame->GetPitch(PLANAR_U); const int row_sizeUV = frame->GetRowSize(PLANAR_U); const int heightUV = frame->GetHeight(PLANAR_U); fileRead(file, dstPtr, pitchUV, row_sizeUV, heightUV); dstPtr = frame->GetWritePtr(PLANAR_V); fileRead(file, dstPtr, pitchUV, row_sizeUV, heightUV); } } file.close(); } if (info) { // overlay on video output: progress indicator ostringstream text; text << "Frame " << n << ".\nRead from \"" << filename << "\""; ApplyMessage(&frame, vi, text.str().c_str(), vi.width/4, TEXT_COLOR,0,0 , env); } return frame; }
PVideoFrame ImageWriter::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame frame = child->GetFrame(n, env); // check bounds if ((n<start)||(n>end)) { if (info) { ostringstream ss; ss << "ImageWriter: frame " << n << " not in range"; env->MakeWritable(&frame); ApplyMessage(&frame, vi, ss.str().c_str(), vi.width/4, TEXT_COLOR,0,0 , env); } return frame; } // construct filename ostringstream fn_oss; fn_oss << base_name << setfill('0') << setw(6) << n << '.' << ext; string filename = fn_oss.str(); if (!lstrcmpi(ext, "ebmp")) /* Use internal 'ebmp' writer */ { // initialize file object ofstream file(filename.c_str(), ios::out | ios::trunc | ios::binary); if (!file) { ostringstream ss; ss << "ImageWriter: could not create file '" << filename << "'"; env->MakeWritable(&frame); ApplyMessage(&frame, vi, ss.str().c_str(), vi.width/4, TEXT_COLOR,0,0 , env); return frame; } // write headers file.write(reinterpret_cast<const char *>( &fileHeader ), sizeof(BITMAPFILEHEADER)); file.write(reinterpret_cast<const char *>( &infoHeader ), sizeof(BITMAPINFOHEADER)); // write raster const BYTE * srcPtr = frame->GetReadPtr(); int pitch = frame->GetPitch(); int row_size = frame->GetRowSize(); int height = frame->GetHeight(); if (0) // (vi.IsY8()) { // write upside down const BYTE * endPtr = srcPtr + pitch * (height-1); fileWrite(file, endPtr, -pitch, row_size, height); } else { fileWrite(file, srcPtr, pitch, row_size, height); if (vi.IsPlanar()) { srcPtr = frame->GetReadPtr(PLANAR_U); pitch = frame->GetPitch(PLANAR_U); row_size = frame->GetRowSize(PLANAR_U); height = frame->GetHeight(PLANAR_U); fileWrite(file, srcPtr, pitch, row_size, height); srcPtr = frame->GetReadPtr(PLANAR_V); fileWrite(file, srcPtr, pitch, row_size, height); } } // clean up file.close(); } else { /* Use DevIL library */ // Set up DevIL ILuint myImage=0; ilGenImages(1, &myImage); // Initialize 1 image structure ilBindImage(myImage); // Set this as the current image const ILenum il_format = vi.IsRGB32() ? IL_BGRA : IL_BGR; // Set image parameters if (IL_TRUE == ilTexImage(vi.width, vi.height, 1, vi.BitsPerPixel() / 8, il_format, IL_UNSIGNED_BYTE, NULL)) { // Program actual image raster const BYTE * srcPtr = frame->GetReadPtr(); int pitch = frame->GetPitch(); for (int y=0; y<vi.height; ++y) { ilSetPixels(0, y, 0, vi.width, 1, 1, il_format, IL_UNSIGNED_BYTE, (void*) srcPtr); srcPtr += pitch; } // DevIL writer fails if the file exists, so delete first DeleteFile(filename.c_str()); // Save to disk (format automatically inferred from extension) ilSaveImage(const_cast<char * const> (filename.c_str()) ); } // Get errors if any ILenum err = ilGetError(); // Clean up ilDeleteImages(1, &myImage); if (err != IL_NO_ERROR) { ostringstream ss; ss << "ImageWriter: error '" << getErrStr(err) << "' in DevIL library\n writing file " << filename; env->MakeWritable(&frame); ApplyMessage(&frame, vi, ss.str().c_str(), vi.width/4, TEXT_COLOR,0,0 , env); return frame; } } if (info) { // overlay on video output: progress indicator ostringstream text; text << "Frame " << n << " written to: " << filename; env->MakeWritable(&frame); ApplyMessage(&frame, vi, text.str().c_str(), vi.width/4, TEXT_COLOR,0,0 , env); } return frame; }