Example #1
0
static void cache_manager_render_reset(CleanData *cd)
{
	filelist_free(cd->list);
	cd->list = NULL;

	filelist_free(cd->list_dir);
	cd->list_dir = NULL;

	thumb_loader_free((ThumbLoader *)cd->tl);
	cd->tl = NULL;
}
Example #2
0
int file_collect_archive_content_( file_archive_info_t * const archive )
{
    int fd;
    char fl_magic[ SAIAMAG ];
    const char * path = object_str( archive->file->name );

    if ( ! filelist_empty( archive->members ) ) filelist_free( archive->members );

    if ( ( fd = open( path, O_RDONLY, 0 ) ) < 0 )
        return -1;

    if ( read( fd, fl_magic, SAIAMAG ) != SAIAMAG ||
            lseek( fd, 0, SEEK_SET ) == -1 )
    {
        close( fd );
        return -1;
    }

    if ( !strncmp( AIAMAG, fl_magic, SAIAMAG ) )
    {
        /* read small variant */
        collect_archive_content_small( fd, archive );
    }
#ifdef AR_HSZ_BIG
    else if ( !strncmp( AIAMAGBIG, fl_magic, SAIAMAG ) )
    {
        /* read big variant */
        collect_archive_content_big( fd, archive );
    }
#endif

    close( fd );

    return 0;
}
Example #3
0
static void bar_pane_comment_set_selection(PaneCommentData *pcd, gboolean append)
{
	GList *list = NULL;
	GList *work;
	gchar *comment = NULL;

	comment = text_widget_text_pull(pcd->comment_view);

	list = layout_selection_list(pcd->pane.lw);
	list = file_data_process_groups_in_selection(list, FALSE, NULL);

	work = list;
	while (work)
		{
		FileData *fd = work->data;
		work = work->next;
		if (fd == pcd->fd) continue;

		if (append)
			{
			metadata_append_string(fd, pcd->key, comment);
			}
		else
			{
			metadata_write_string(fd, pcd->key, comment);
			}
		}

	filelist_free(list);
	g_free(comment);
}
Example #4
0
static void vd_destroy_cb(GtkWidget *widget, gpointer data)
{
	ViewDir *vd = data;

	file_data_unregister_notify_func(vd_notify_cb, vd);

	if (vd->popup)
		{
		g_signal_handlers_disconnect_matched(G_OBJECT(vd->popup), G_SIGNAL_MATCH_DATA,
						     0, 0, 0, NULL, vd);
		gtk_widget_destroy(vd->popup);
		}

	switch (vd->type)
	{
	case DIRVIEW_LIST: vdlist_destroy_cb(widget, data); break;
	case DIRVIEW_TREE: vdtree_destroy_cb(widget, data); break;
	}

	if (vd->pf) folder_icons_free(vd->pf);
	if (vd->drop_list) filelist_free(vd->drop_list);

	if (vd->dir_fd) file_data_unref(vd->dir_fd);
	if (vd->info) g_free(vd->info);

	g_free(vd);
}
Example #5
0
static void bar_pane_keywords_set_selection(PaneKeywordsData *pkd, gboolean append)
{
	GList *keywords = NULL;
	GList *list = NULL;
	GList *work;

	keywords = keyword_list_pull(pkd->keyword_view);

	list = layout_selection_list(pkd->pane.lw);
	list = file_data_process_groups_in_selection(list, FALSE, NULL);

	work = list;
	while (work)
		{
		FileData *fd = work->data;
		work = work->next;

		if (append)
			{
			metadata_append_list(fd, KEYWORD_KEY, keywords);
			}
		else
			{
			metadata_write_list(fd, KEYWORD_KEY, keywords);
			}
		}

	filelist_free(list);
	string_list_free(keywords);
}
Example #6
0
static EditorFlags editor_command_done(EditorData *ed)
{
	EditorFlags flags;

	if (ed->vd)
		{
		if (ed->count == ed->total)
			{
			editor_verbose_window_progress(ed, _("done"));
			}
		else
			{
			editor_verbose_window_progress(ed, _("stopped by user"));
			}
		editor_verbose_window_enable_close(ed->vd);
		}

	/* free the not-handled items */
	if (ed->list)
		{
		ed->flags |= EDITOR_ERROR_SKIPPED;
		if (ed->callback) ed->callback(NULL, ed->flags, ed->list, ed->data);
		filelist_free(ed->list);
		ed->list = NULL;
		}

	ed->count = 0;

	flags = EDITOR_ERRORS(ed->flags);

	if (!ed->vd) editor_data_free(ed);

	return flags;
}
Example #7
0
void file_dialog_close(FileDialog *fdlg)
{
	file_data_unref(fdlg->source_fd);
	g_free(fdlg->dest_path);
	if (fdlg->source_list) filelist_free(fdlg->source_list);

	generic_dialog_close(GENERIC_DIALOG(fdlg));
}
Example #8
0
static void cache_maintain_home_close(CMData *cm)
{
	if (cm->idle_id) g_source_remove(cm->idle_id);
	if (cm->gd) generic_dialog_close(cm->gd);
	filelist_free(cm->list);
	g_list_free(cm->done_list);
	g_free(cm);
}
Example #9
0
static void view_window_set_list(ViewWindow *vw, GList *list)
{

	filelist_free(vw->list);
	vw->list = NULL;
	vw->list_pointer = NULL;

	vw->list = filelist_copy(list);
}
Example #10
0
static void collect_manager_refresh(void)
{
	GList *list;
	GList *work;
	FileData *dir_fd;

	dir_fd = file_data_new_simple(get_collections_dir());
	filelist_read(dir_fd, &list, NULL);
	file_data_unref(dir_fd);

	work = collection_manager_entry_list;
	while (work && list)
		{
		CollectManagerEntry *entry;
		GList *list_step;

		entry = work->data;
		work = work->next;

		list_step = list;
		while (list_step && entry)
			{
			FileData *fd;

			fd = list_step->data;
			list_step = list_step->next;

			if (strcmp(fd->path, entry->path) == 0)
				{
				list = g_list_remove(list, fd);
				file_data_unref(fd);

				entry = NULL;
				}
			else
				{
				collect_manager_entry_free(entry);
				}
			}
		}

	work = list;
	while (work)
		{
		FileData *fd;

		fd = work->data;
		work = work->next;

		collect_manager_entry_new(fd->path);
		}

	filelist_free(list);
}
Example #11
0
static void cache_manager_standard_clean_close_cb(GenericDialog *gd, gpointer data)
{
	CleanData *cd = data;

	if (!gtk_widget_get_sensitive(cd->button_close)) return;

	generic_dialog_close(cd->gd);

	thumb_loader_std_thumb_file_validate_cancel(cd->tl);
	filelist_free(cd->list);
	g_free(cd);
}
Example #12
0
void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile)
{
	/* only NULL in rare cases - [#29734] */
	if (sfile->files) {
		thumbnails_stop(wm, sfile->files);
		filelist_freelib(sfile->files);
		filelist_free(sfile->files);
	}

	sfile->params->highlight_file = -1;
	WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
Example #13
0
static void bogotune_free(void)
{
    xfree(ns_scores);
    xfree(sp_scores);

    filelist_free(ham_files);
    filelist_free(spam_files);

    tunelist_free(ns_msglists);
    tunelist_free(sp_msglists);
    tunelist_free(ns_and_sp);

    word_free(w_msg_count);

    token_cleanup();
    mime_cleanup();

    xfree(ds_path);

    return;
}
Example #14
0
void ED_fileselect_clear(struct bContext *C, struct SpaceFile *sfile)
{
	/* only NULL in rare cases - [#29734] */
	if (sfile->files) {
		thumbnails_stop(sfile->files, C);
		filelist_freelib(sfile->files);
		filelist_free(sfile->files);
	}

	sfile->params->active_file = -1;
	WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL);
}
Example #15
0
/**
 * \brief Callback for adding selected keyword to all selected images.
 */
static void bar_pane_keywords_add_to_selected_cb(GtkWidget *menu_widget, gpointer data)
{
	PaneKeywordsData *pkd = data;
	GtkTreeIter iter; /* This is the iter which initial holds the current keyword */
	GtkTreeIter child_iter;
	GtkTreeModel *model;
	GtkTreeModel *keyword_tree;
	GList *list, *work;
	GList *keywords = NULL;

	GtkTextBuffer *keyword_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pkd->keyword_view));

	/* Aquire selected keyword */
	if (pkd->click_tpath)
		{
		gboolean is_keyword = TRUE;

		model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview));
	        if (!gtk_tree_model_get_iter(model, &iter, pkd->click_tpath)) return;
		gtk_tree_model_get(model, &iter, FILTER_KEYWORD_COLUMN_IS_KEYWORD, &is_keyword, -1);
		if (!is_keyword) return;
		}
	else
		return;

	keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model));
	gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &child_iter, &iter);

	list = keyword_list_pull(pkd->keyword_view); /* Get the left keyword view */

	/* Now set the current image */
	keyword_tree_set(keyword_tree, &child_iter, &list);

	keyword_list_push(pkd->keyword_view, list); /* Set the left keyword view */
	string_list_free(list);

	bar_pane_keywords_changed(keyword_buffer, pkd); /* Get list of all keywords in the hierarchy */

	gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &child_iter, &iter);
	keywords = keyword_tree_get(keyword_tree, &child_iter);

	list = layout_selection_list(pkd->pane.lw);
	work = list;
	while (work)
		{
		FileData *fd = work->data;
		work = work->next;
		metadata_append_list(fd, KEYWORD_KEY, keywords);
		}
	filelist_free(list);
	string_list_free(keywords);
}
Example #16
0
static EditorFlags editor_command_next_finish(EditorData *ed, gint status)
{
	gint cont = ed->stopping ? EDITOR_CB_SKIP : EDITOR_CB_CONTINUE;

	if (status)
		ed->flags |= EDITOR_ERROR_STATUS;

	if (ed->flags & EDITOR_FOR_EACH)
		{
		/* handle the first element from the list */
		GList *fd_element = ed->list;

		ed->list = g_list_remove_link(ed->list, fd_element);
		if (ed->callback)
			{
			cont = ed->callback(ed->list ? ed : NULL, ed->flags, fd_element, ed->data);
			if (ed->stopping && cont == EDITOR_CB_CONTINUE) cont = EDITOR_CB_SKIP;
			}
		filelist_free(fd_element);
		}
	else
		{
		/* handle whole list */
		if (ed->callback)
			cont = ed->callback(NULL, ed->flags, ed->list, ed->data);
		filelist_free(ed->list);
		ed->list = NULL;
		}

	switch (cont)
		{
		case EDITOR_CB_SUSPEND:
			return EDITOR_ERRORS(ed->flags);
		case EDITOR_CB_SKIP:
			return editor_command_done(ed);
		}

	return editor_command_next_start(ed);
}
Example #17
0
static void vf_popup_destroy_cb(GtkWidget *widget, gpointer data)
{
	ViewFile *vf = data;

	switch (vf->type)
	{
	case FILEVIEW_LIST: vflist_popup_destroy_cb(widget, data); break;
	case FILEVIEW_ICON: vficon_popup_destroy_cb(widget, data); break;
	}

	filelist_free(vf->editmenu_fd_list);
	vf->editmenu_fd_list = NULL;
}
Example #18
0
// check if filelist is sequential
int MainWindow::checkFileSequence(QFileInfoList list)
{
    QString msg;
    int     rc;

    filelist_t *fileList = QStringToFilelist(list);

    if (fileList == NULL) {
        filelist_free(fileList);
        return OPENDCP_ERROR;
    }

    qDebug() << "files: " << fileList->nfiles;

    if (order_indexed_files(fileList->files, fileList->nfiles) != OPENDCP_NO_ERROR) {
        if (QMessageBox::question(this, tr("Could not order files"), msg, QMessageBox::No,QMessageBox::Yes) == QMessageBox::No) {
            filelist_free(fileList);
            return OPENDCP_ERROR;
        }
    }

    rc = ensure_sequential(fileList->files, fileList->nfiles);

    qDebug() << rc;

    if (rc) {
        QTextStream(&msg) << tr("File list does not appear to be sequential between ") << list.at(rc).fileName();
        QTextStream(&msg) << tr(" and ") << list.at(rc+1).fileName() << tr(". Do you wish to continue?");
        if (QMessageBox::question(this, tr("File Sequence Mismatch"), msg, QMessageBox::No,QMessageBox::Yes) == QMessageBox::No) {
            filelist_free(fileList);
            return OPENDCP_ERROR;
        }
    }

    filelist_free(fileList);

    return OPENDCP_NO_ERROR;
}
Example #19
0
static void view_window_destroy_cb(GtkWidget *widget, gpointer data)
{
	ViewWindow *vw = data;

	view_window_list = g_list_remove(view_window_list, vw);

	view_slideshow_stop(vw);
	fullscreen_stop(vw->fs);

	filelist_free(vw->list);

	file_data_unregister_notify_func(view_window_notify_cb, vw);

	g_free(vw);
}
Example #20
0
static void cache_manager_standard_clean_close_cb(GenericDialog *gd, gpointer data)
{
	CleanData *cd = data;

#if GTK_CHECK_VERSION(2,20,0)
	if (!gtk_widget_get_sensitive(cd->button_close)) return;
#else
	if (!GTK_WIDGET_SENSITIVE(cd->button_close)) return;
#endif

	generic_dialog_close(cd->gd);

	thumb_loader_std_thumb_file_validate_cancel(cd->tl);
	filelist_free(cd->list);
	g_free(cd);
}
Example #21
0
void MxfWriter::run()
{
    int i = 0;

    opendcpMxf->mxf.frame_done.callback = MxfWriter::frameDoneCb;
    opendcpMxf->mxf.frame_done.argument = this;

    filelist_t *fileList = filelist_alloc(mxfFileList.size());

    while (!mxfFileList.isEmpty()) {
        sprintf(fileList->files[i++],"%s",mxfFileList.takeFirst().absoluteFilePath().toUtf8().data());
    }

    rc = write_mxf(opendcpMxf, fileList, mxfOutputFile.toUtf8().data());

    filelist_free(fileList);

    emit setResult(rc);
    emit finished();
}
Example #22
0
void file_change_dir(struct SpaceFile *sfile, int checkdir)
{
	if (sfile->params) {

		if(checkdir && BLI_is_dir(sfile->params->dir)==0) {
			BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir));
			/* could return but just refresh the current dir */
		}

		filelist_setdir(sfile->files, sfile->params->dir);

		if(folderlist_clear_next(sfile))
			folderlist_free(sfile->folders_next);

		folderlist_pushdir(sfile->folders_prev, sfile->params->dir);

		filelist_free(sfile->files);
		sfile->params->active_file = -1;
	}
}
Example #23
0
static void cache_manager_standard_clean_done(CleanData *cd)
{
	gtk_widget_set_sensitive(cd->button_stop, FALSE);
	gtk_widget_set_sensitive(cd->button_close, TRUE);

	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress), 1.0);
	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(cd->progress), _("done"));

	if (cd->idle_id)
		{
		g_source_remove(cd->idle_id);
		cd->idle_id = 0;
		}

	thumb_loader_std_thumb_file_validate_cancel(cd->tl);
	cd->tl = NULL;

	filelist_free(cd->list);
	cd->list = NULL;
}
Example #24
0
void view_window_new(FileData *fd)
{
	GList *list;

	if (file_extension_match(fd->path, GQ_COLLECTION_EXT))
		{
		ViewWindow *vw;
		CollectionData *cd;
		CollectInfo *info;

		cd = collection_new(fd->path);
		if (collection_load(cd, fd->path, COLLECTION_LOAD_NONE))
			{
			info = collection_get_first(cd);
			}
		else
			{
			collection_unref(cd);
			cd = NULL;
			info = NULL;
			}
		vw = real_view_window_new(NULL, NULL, cd, info);
		if (vw && cd)
			{
			g_signal_connect(G_OBJECT(vw->window), "destroy",
					 G_CALLBACK(view_window_collection_unref_cb), cd);
			}
		}
	else if (isdir(fd->path) && filelist_read(fd, &list, NULL))
		{
		list = filelist_sort_path(list);
		list = filelist_filter(list, FALSE);
		real_view_window_new(NULL, list, NULL, NULL);
		filelist_free(list);
		}
	else
		{
		real_view_window_new(fd, NULL, NULL, NULL);
		}
}
Example #25
0
int main(int argc, char *argv[])
{
  GList *list;
  GList *l;

  if ( argc != 2 ) {
    fprintf(stderr, "Usage: filelist_test <regex>\n");
    exit(1);
  }

  list = filelist(argv[1]);

  l = list;
  while ( l != NULL ) {
    printf("%s\n", (char *) l->data);
    l = l->next;
  }

  filelist_free(list);

  return 0;
}
Example #26
0
/* Outputs a sorted list of files/directories matching the mask,
 * to idx.
 */
static void filedb_ls(FILE *fdb, int idx, char *mask, int showall)
{
    int ok = 0, cnt = 0, is = 0;
    char s1[81], *p = NULL;
    struct flag_record user = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
    filedb_entry *fdbe = NULL;
    filelist_t *flist = NULL;

    flist = filelist_new();
    filedb_readtop(fdb, NULL);
    fdbe = filedb_getfile(fdb, ftell(fdb), GET_FULL);
    while (fdbe) {
        ok = 1;
        if (fdbe->stat & FILE_UNUSED)
            ok = 0;
        if (ok && (fdbe->stat & FILE_DIR) && fdbe->flags_req) {
            /* Check permissions */
            struct flag_record req = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };

            break_down_flags(fdbe->flags_req, &req, NULL);
            get_user_flagrec(dcc[idx].user, &user, dcc[idx].u.file->chat->con_chan);
            if (!flagrec_ok(&req, &user)) {
                ok = 0;
            }
        }
        if (ok)
            is = 1;
        if (ok && !wild_match_file(mask, fdbe->filename))
            ok = 0;
        if (ok && (fdbe->stat & FILE_HIDDEN) && !(showall))
            ok = 0;
        if (ok) {
            /* Display it! */
            if (cnt == 0) {
                dprintf(idx, FILES_LSHEAD1);
                dprintf(idx, FILES_LSHEAD2);
            }
            filelist_add(flist, fdbe->filename);
            if (fdbe->stat & FILE_DIR) {
                char *s2 = NULL, *s3 = NULL;

                /* Too long? */
                if (strlen(fdbe->filename) > 45) {
                    /* Display the filename on its own line. */
                    s2 = nmalloc(strlen(fdbe->filename) + 3);
                    sprintf(s2, "%s/\n", fdbe->filename);
                    filelist_addout(flist, s2);
                    my_free(s2);
                } else {
                    s2 = nmalloc(strlen(fdbe->filename) + 2);
                    sprintf(s2, "%s/", fdbe->filename);
                }
                /* Note: You have to keep the sprintf and the nmalloc statements
                 *       in sync, i.e. always check that you allocate enough
                 *       memory.
                 */
                if ((fdbe->flags_req) && (user.global &(USER_MASTER | USER_JANITOR))) {
                    s3 = nmalloc(42 + strlen(s2 ? s2 : "") + 6 +
                                 strlen(FILES_REQUIRES) + strlen(fdbe->flags_req) + 1 +
                                 strlen(fdbe->chan ? fdbe->chan : "") + 1);
                    sprintf(s3, "%-30s <DIR%s>  (%s %s%s%s)\n", s2,
                            fdbe->stat & FILE_SHARE ?
                            " SHARE" : "", FILES_REQUIRES, fdbe->flags_req,
                            fdbe->chan ? " " : "", fdbe->chan ? fdbe->chan : "");
                } else {
                    s3 = nmalloc(38 + strlen(s2 ? s2 : ""));
                    sprintf(s3, "%-30s <DIR>\n", s2 ? s2 : "");
                }
                if (s2)
                    my_free(s2);
                filelist_addout(flist, s3);
                my_free(s3);
            } else {
                char s2[41], t[50], *s3 = NULL, *s4;

                s2[0] = 0;
                if (showall) {
                    if (fdbe->stat & FILE_SHARE)
                        strcat(s2, " (shr)");
                    if (fdbe->stat & FILE_HIDDEN)
                        strcat(s2, " (hid)");
                }
                egg_strftime(t, 10, "%d%b%Y", localtime(&fdbe->uploaded));
                if (fdbe->size < 1024)
                    sprintf(s1, "%5d", fdbe->size);
                else
                    sprintf(s1, "%4dk", (int) (fdbe->size / 1024));
                if (fdbe->sharelink)
                    strcpy(s1, "     ");
                /* Too long? */
                if (strlen(fdbe->filename) > 30) {
                    s3 = nmalloc(strlen(fdbe->filename) + 2);
                    sprintf(s3, "%s\n", fdbe->filename);
                    filelist_addout(flist, s3);
                    my_free(s3);
                    /* Causes filename to be displayed on its own line */
                } else
                    malloc_strcpy(s3, fdbe->filename);
                s4 = nmalloc(69 + strlen(s3 ? s3 : "") + strlen(s1) +
                             strlen(fdbe->uploader) + strlen(t) + strlen(s2));
                sprintf(s4, "%-30s %s  %-9s (%s)  %6d%s\n", s3 ? s3 : "", s1,
                        fdbe->uploader, t, fdbe->gots, s2);
                if (s3)
                    my_free(s3);
                filelist_addout(flist, s4);
                my_free(s4);
                if (fdbe->sharelink) {
                    s4 = nmalloc(9 + strlen(fdbe->sharelink));
                    sprintf(s4, "   --> %s\n", fdbe->sharelink);
                    filelist_addout(flist, s4);
                    my_free(s4);
                }
            }
            if (fdbe->desc) {
                p = strchr(fdbe->desc, '\n');
                while (p != NULL) {
                    *p = 0;
                    if ((fdbe->desc)[0]) {
                        char *sd;

                        sd = nmalloc(strlen(fdbe->desc) + 5);
                        sprintf(sd, "   %s\n", fdbe->desc);
                        filelist_addout(flist, sd);
                        my_free(sd);
                    }
                    strcpy(fdbe->desc, p + 1);
                    p = strchr(fdbe->desc, '\n');
                }
                if ((fdbe->desc)[0]) {
                    char *sd;

                    sd = nmalloc(strlen(fdbe->desc) + 5);
                    sprintf(sd, "   %s\n", fdbe->desc);
                    filelist_addout(flist, sd);
                    my_free(sd);
                }
            }
            cnt++;
        }
        free_fdbe(&fdbe);
        fdbe = filedb_getfile(fdb, ftell(fdb), GET_FULL);
    }
    if (is == 0)
        dprintf(idx, FILES_NOFILES);
    else if (cnt == 0)
        dprintf(idx, FILES_NOMATCH);
    else {
        filelist_sort(flist);
        filelist_idxshow(flist, idx);
        dprintf(idx, "--- %d file%s.\n", cnt, cnt != 1 ? "s" : "");
    }
    filelist_free(flist);
}
Example #27
0
/* This checks all files in ~/GQ_RC_DIR/thumbnails and
 * removes them if thay have no source counterpart.
 * (this assumes all cache files have an extension of 4 chars including '.')
 */
gint cache_maintain_home_dir(const gchar *dir, gint recursive, gint clear)
{
	gchar *base;
	gint base_length;
	GList *dlist = NULL;
	FileData *dir_fd;
	GList *flist = NULL;
	gboolean still_have_a_file = FALSE;

	DEBUG_1("maintainance check: %s", dir);

	base_length = strlen(homedir()) + strlen("/") + strlen(GQ_CACHE_RC_THUMB);
	base = g_strconcat(homedir(), "/", GQ_CACHE_RC_THUMB, dir, NULL);
	dir_fd = file_data_new_simple(base);
	g_free(base);

	if (filelist_read(dir_fd, &flist, &dlist))
		{
		GList *work;

		work = dlist;
		while (work)
			{
			FileData *fd = work->data;
			if (recursive && strlen(fd->path) > base_length &&
			    !cache_maintain_home_dir(fd->path + base_length, recursive, clear))
				{
				DEBUG_1("Deleting thumb dir: %s", fd->path);
				if (!rmdir_utf8(fd->path))
					{
					log_printf("Unable to delete dir: %s\n", fd->path);
					}
				}
			else
				{
				still_have_a_file = TRUE;
				}
			work = work->next;
			}

		work = flist;
		while (work)
			{
			FileData *fd = work->data;
			gchar *path = g_strdup(fd->path);
			gchar *dot;

			dot = extension_find_dot(path);

			if (dot) *dot = '\0';
			if (clear ||
			    (strlen(path) > base_length && !isfile(path + base_length)) )
				{
				if (dot) *dot = '.';
				if (!unlink_file(path)) log_printf("failed to delete:%s\n", path);
				}
			else
				{
				still_have_a_file = TRUE;
				}
			g_free(path);

			work = work->next;
			}
		}

	filelist_free(dlist);
	filelist_free(flist);
	file_data_unref(dir_fd);

	return still_have_a_file;
}
Example #28
0
/* This checks relative caches in dir/.thumbnails and
 * removes them if they have no source counterpart.
 */
gint cache_maintain_dir(FileData *dir_fd, gint recursive, gint clear)
{
	GList *list = NULL;
	gchar *cachedir;
	FileData *cachedir_fd;
	gboolean still_have_a_file = FALSE;
	GList *work;

	cachedir = g_build_filename(dir, GQ_CACHE_LOCAL_THUMB, NULL);
	cachedir_fd = file_data_new_simple(cachedir);
	g_free(cachedir);

	filelist_read(cachedir_fd, &list, NULL);
	work = list;

	while (work)
		{
		FileData *fd;
		gchar *source;

		fd = work->data;
		work = work->next;

		source = g_build_filename(dir->path, fd->name, NULL);

		if (clear ||
		    extension_truncate(source, GQ_CACHE_EXT_THUMB) ||
		    extension_truncate(source, GQ_CACHE_EXT_SIM))
			{
			if (!clear && isfile(source))
				{
				still_have_a_file = TRUE;
				}
			else
				{
				if (!unlink_file(fd->path))
					{
					DEBUG_1("Failed to remove cache file %s", fd->path);
					still_have_a_file = TRUE;
					}
				}
			}
		else
			{
			still_have_a_file = TRUE;
			}
		g_free(source);
		}

	filelist_free(list);
	file_data_unref(cachedir_fd);

	if (recursive)
		{
		list = NULL;

		filelist_read(dir_fd, NULL, &list);
		work = list;
		while (work)
			{
			FileData *fd = work->data;
			work = work->next;

			still_have_a_file |= cache_maintain_dir(fd->path, recursive, clear);
			}

		filelist_free(list);
		}

	return still_have_a_file;
}
/*
** k2pdfopt_proc_one() is the main source file processing function in k2pdfopt.
** 
** Depending on the value of rot_deg, it either determines the correct rotation of
** the passed file, or it processes it and converts it.
**
** The basic idea is to parse the source document into rectangular regions
** (held in the BMPREGION structures) and then to place these regions into
** the master destination bitmap (kept track of in MASTERINFO structure).
** You can think of this bitmap as a sort of "infinitely scrolling" output
** bitmap which is then cut into output pages.
**
** The bmpregion_source_page_add() function parses the source file.
**
** The masterinfo_publish() cuts the output bitmap into destination pages.
**
** If rot_deg == SRCROT_AUTO, then the rotation correction of the source
** file is computed and returned, but no other processing is done.
**
** Otherwise, the source file is processed.
*/
static double k2pdfopt_proc_one(K2PDFOPT_SETTINGS *k2settings0,char *filename,double rot_deg,
                                K2PDFOPT_OUTPUT *k2out)

    {
    static K2PDFOPT_SETTINGS _k2settings,*k2settings;
    static MASTERINFO _masterinfo,*masterinfo;
    static PDFFILE _mpdf,*mpdf;
    char dstfile[MAXFILENAMELEN];
    char markedfile[MAXFILENAMELEN];
    char rotstr[128];
    WILLUSBITMAP _src,*src;
    WILLUSBITMAP _srcgrey,*srcgrey;
    WILLUSBITMAP _marked,*marked;
    WILLUSBITMAP preview_internal;
    int i,status,pw,np,src_type,second_time_through,or_detect,orep_detect,preview;
    int pagecount,pagestep,pages_done,local_tocwrites;
    int errcnt,pixwarn;
    FILELIST *fl,_fl;
    int folder,dpi;
    double size,bormean;
    char *mupdffilename;
    extern int k2mark_page_count;
    static char *funcname="k2pdfopt_proc_one";
    static char *readerr=TTEXT_WARN "\a\n ** ERROR reading page %d from " TTEXT_BOLD2 "%s" TTEXT_WARN ".\n\n" TTEXT_NORMAL;
    static char *readlimit=TTEXT_WARN "\a\n ** (No more read errors will be echoed for file %s.)\n\n" TTEXT_NORMAL;
/*
extern void willus_mem_debug_update(char *);
*/

#if (WILLUSDEBUGX & 1)
printf("@k2pdfopt_proc_one(%s)\n",filename);
#endif
/*
printf("@k2pdfopt_proc_one(filename='%s', rot_deg=%g, preview_bitmap=%p)\n",filename,rot_deg,k2out->bmp);
*/

    /*
    ** Check to see if we're only echoing page info
    */
    if (k2settings0->info)
        {
#ifdef HAVE_MUPDF_LIB
        char *buf;
        int *pagelist;
        pagelist_get_array(&pagelist,k2settings0->pagelist);
/*
{
int i;
for (i=0;pagelist!=NULL&&pagelist[i]>=0;i++)
printf("pagelist[%d]=%d\n",i,pagelist[i]);
printf("pagelist[%d]=%d\n",i,pagelist[i]);
}
*/
        wmupdfinfo_get(filename,pagelist,&buf);
        printf("%s",buf);
        if (buf!=NULL)
            free(buf);
        if (pagelist!=NULL)
            free(pagelist);
#else
        printf("FILE: %s\n",filename);
        printf("Cannot print file info.  MuPDF not compiled into application.\n");
#endif
        return(0.);
        }
    local_tocwrites=0;
    k2out->status = 1;
    k2settings=&_k2settings;
    k2pdfopt_settings_copy(k2settings,k2settings0);
#ifdef HAVE_K2GUI
    if (k2gui_active())
        k2gui_cbox_set_filename(filename);
#endif
    mpdf=&_mpdf;
    /* Must be called once per conversion to init margins / devsize / output size */
    k2pdfopt_settings_sanity_check(k2settings);
    k2pdfopt_settings_new_source_document_init(k2settings);
    errcnt=0;
    pixwarn=0;
    mupdffilename=_masterinfo.srcfilename;
    strncpy(mupdffilename,filename,MAXFILENAMELEN-1);
    mupdffilename[MAXFILENAMELEN-1]='\0';
    or_detect=OR_DETECT(rot_deg);
    orep_detect=OREP_DETECT(k2settings);
    if ((fabs(k2settings->src_rot-SRCROT_AUTO)<.5 || orep_detect) && !or_detect)
        second_time_through=1;
    else
        second_time_through=0;
    /* Don't care about rotation if just echoing page count */
    if (k2settings->echo_source_page_count && second_time_through==0)
        return(0.);
    if (or_detect && k2settings->src_dpi>300)
        dpi=300;
    else
        dpi=k2settings->src_dpi;
    folder=(wfile_status(filename)==2);
    /*
    if (folder && !second_time_through)
        k2printf("Processing " TTEXT_INPUT "BITMAP FOLDER %s" TTEXT_NORMAL "...\n",
               filename);
    */
    /*
    else
        k2printf("Processing " TTEXT_BOLD2 "PDF FILE %s" TTEXT_NORMAL "...\n",
               filename);
    */
    fl=&_fl;
    filelist_init(fl);
    if (folder)
        {
        char basename[MAXFILENAMELEN];
        static char *iolist[]={"*.png","*.jpg",""};
        static char *eolist[]={""};

        wfile_basespec(basename,filename);
        if (!second_time_through)
            k2printf("Searching folder " TTEXT_BOLD2 "%s" TTEXT_NORMAL " ... ",basename);
        fflush(stdout);
        filelist_fill_from_disk(fl,filename,iolist,eolist,0,0);
        if (fl->n<=0)
            {
            if (!second_time_through)
                k2printf(TTEXT_WARN "\n** No bitmaps found in folder %s.\n\n" 
                        TTEXT_NORMAL,filename);
            k2out->status=2;
            return(0.);
            }
        if (!second_time_through)
            k2printf("%d bitmaps found in %s.\n",(int)fl->n,filename);
        filelist_sort_by_name(fl);
        }
    src=&_src;
    srcgrey=&_srcgrey;
    marked=&_marked;
    bmp_init(src);
    bmp_init(srcgrey);
    bmp_init(marked);
    pw=0;
    src_type = get_source_type(filename);
#ifndef HAVE_DJVU_LIB
    if (src_type==SRC_TYPE_DJVU)
        {
        if (!or_detect)
            k2printf(TTEXT_WARN
                    "\a\n\n** DjVuLibre not compiled into this version of k2pdfopt. **\n\n"
                          "** Cannot process file %s. **\n\n" TTEXT_NORMAL,filename);
        k2out->status=3;
        return(0.);
        }
#endif
    if (src_type==SRC_TYPE_PS)
        k2settings->usegs=1;
    /*
    ** Turn off native PDF output if source is not PDF
    */
    if (src_type!=SRC_TYPE_PDF)
        {
        if (k2settings->use_crop_boxes && !or_detect)
            k2printf(TTEXT_WARN
                     "\n** Native PDF output mode turned off on file %s. **\n"
                     "** (It is not a PDF file.) **\n\n",filename);
        k2settings->use_crop_boxes=0;
#ifdef HAVE_OCR_LIB
        if (k2settings->dst_ocr=='m')
            k2settings->dst_ocr=0;
#endif
        }
    masterinfo=&_masterinfo;
    masterinfo_init(masterinfo,k2settings);
    if (k2settings->preview_page!=0 && !or_detect)
        {
        preview=1;
        if (k2out->bmp!=NULL)
            masterinfo->preview_bitmap=k2out->bmp;
        else
            {
            masterinfo->preview_bitmap=&preview_internal;
            bmp_init(masterinfo->preview_bitmap);
            }
        }
    else
        preview=0;
    if (!or_detect && !preview)
        {
        static int dstfilecount=0;

        wfile_newext(dstfile,filename,"");
        dstfilecount++;
        filename_substitute(dstfile,k2settings->dst_opname_format,filename,dstfilecount,"pdf");
#ifdef HAVE_OCR_LIB
        if (k2settings->ocrout[0]!='\0' && k2settings->dst_ocr)
            filename_substitute(masterinfo->ocrfilename,k2settings->ocrout,filename,dstfilecount,"txt");
        else
#endif
            masterinfo->ocrfilename[0]='\0';
        if (!filename_comp(dstfile,filename))
            {
            k2printf(TTEXT_WARN "\n\aSource file and ouput file have the same name!" TTEXT_NORMAL "\n\n");
            k2printf("    Source file = '%s'\n",filename);
            k2printf("    Output file = '%s'\n",dstfile);
            k2printf("    Output file name format string = '%s'\n",k2settings->dst_opname_format);
            k2printf("\nOperation aborted.\n");
            k2sys_exit(k2settings,50);
            }
        if ((status=overwrite_fail(dstfile,k2settings->overwrite_minsize_mb))!=0)
            {
            masterinfo_free(masterinfo,k2settings);
            if (folder)
                filelist_free(fl);
            if (status<0)
                k2sys_exit(k2settings,20);
            k2out->status=4;
            return(0.);
            }
        {
        int can_write;
        if (!k2settings->use_crop_boxes)
            can_write = (pdffile_init(&masterinfo->outfile,dstfile,1)!=NULL);
        else
            {
            FILE *f1;
            f1 = wfile_fopen_utf8(dstfile,"w");
            can_write = (f1!=NULL);
            if (f1!=NULL)
                {
                fclose(f1);
                wfile_remove_utf8(dstfile);
                }
            if (!can_write)
                {
                k2printf(TTEXT_WARN "\n\aCannot open PDF file %s for output!" TTEXT_NORMAL "\n\n",dstfile);
#ifdef HAVE_K2GUI
                if (k2gui_active())
                    {
                    k2gui_okay("Failed to open output file",
                               "Cannot open PDF file %s for output!\n"
                               "Maybe another application has it open already?\n"
                               "Conversion failed!",dstfile);
                    k2out->status=4;
                    return(0.);
                    }
#endif
                k2sys_exit(k2settings,30);
                }
            }
        }
        k2out->outname=NULL;
        /* Return output file name in k2out for GUI */
        willus_mem_alloc((double **)&k2out->outname,(long)(strlen(dstfile)+1),funcname);
        if (k2out->outname!=NULL)
            strcpy(k2out->outname,dstfile);
        if (k2settings->use_crop_boxes)
            pdffile_close(&masterinfo->outfile);
        if (k2settings->show_marked_source)
            {
            filename_substitute(markedfile,"%s_marked",filename,0,"pdf");
            if (pdffile_init(mpdf,markedfile,1)==NULL)
                {
                k2printf(TTEXT_WARN "\n\aCannot open PDF file %s for marked output!" TTEXT_NORMAL "\n\n",markedfile);
                k2sys_exit(k2settings,40);
                }
            }
        }
    if (src_type==SRC_TYPE_PDF || src_type==SRC_TYPE_DJVU)
        {
        np=file_numpages(filename,mupdffilename,src_type,&k2settings->usegs);
#ifdef HAVE_MUPDF_LIB
        if (src_type==SRC_TYPE_PDF)
            {
            /* Get bookmarks / outline from PDF file */
            if (!or_detect && k2settings->use_toc!=0 && !toclist_valid(k2settings->toclist,NULL))
                {
                masterinfo->outline=wpdfoutline_read_from_pdf_file(mupdffilename);
                /* Save TOC if requested */
                if (k2settings->tocsavefile[0]!='\0')
                    {
                    FILE *f;
                    f=fopen(k2settings->tocsavefile,tocwrites==0?"w":"a");
                    if (f!=NULL)
                        {
                        int i;
                        fprintf(f,"%sFILE: %s\n",tocwrites==0?"":"\n\n",mupdffilename);
                        for (i=strlen(mupdffilename)+6;i>0;i--)
                            fputc('-',f);
                        fprintf(f,"\n");
                        if (masterinfo->outline!=NULL)
                            wpdfoutline_echo2(masterinfo->outline,0,f);
                        else
                            fprintf(f,"(No outline info in file.)\n");
                        fclose(f);
                        tocwrites++;
                        local_tocwrites++;
                        }
                    }
                }
            }
#endif
        }
    else if (src_type==SRC_TYPE_BITMAPFOLDER)
        np=fl->n;
    else
        np=-1;
    if (k2settings->echo_source_page_count)
        {
        printf("\"%s\" page count = %d\n",mupdffilename,np);
        masterinfo_free(masterinfo,k2settings);
        if (folder)
            filelist_free(fl);
        return(0.);
        }
    masterinfo->srcpages = np;
    if (!or_detect && toclist_valid(k2settings->toclist,stdout))
        {
        if (pagelist_valid_page_range(k2settings->toclist))
            masterinfo->outline=wpdfoutline_from_pagelist(k2settings->toclist,masterinfo->srcpages);
        else
            masterinfo->outline=wpdfoutline_read_from_text_file(k2settings->toclist);
        }
    pagecount = np<0 ? -1 : double_pagelist_count(k2settings->pagelist,k2settings->pagexlist,np);
#ifdef HAVE_K2GUI
    if (k2gui_active())
        {
        k2gui_cbox_set_num_pages(pagecount<0 ? 1 : pagecount);
        k2gui_cbox_set_pages_completed(0,NULL);
        }
#endif
    if (pagecount<0 || !or_detect)
        pagestep=1;
    else
        {
        pagestep=pagecount/10;
        if (pagestep<1)
            pagestep=1;
        }
    pages_done=0;
    if (np>0 && pagecount==0)
        {
        if (!second_time_through)
            k2printf("\a\n" TTEXT_WARN "No %ss to convert (-p %s -px %s)!" TTEXT_NORMAL "\n\n",
                     folder?"file":"page",k2settings->pagelist,k2settings->pagexlist);
        masterinfo_free(masterinfo,k2settings);
        if (folder)
            filelist_free(fl);
        k2out->status=5;
        return(0.);
        }
    if (!second_time_through)
        {
        k2printf("Reading ");
        if (pagecount>0)
           {
           if (pagecount<np)
               k2printf("%d out of %d %s%s",pagecount,np,folder?"file":"page",np>1?"s":"");
           else
               k2printf("%d %s%s",np,folder?"file":"page",np>1?"s":"");
           }
        else
           k2printf("%ss",folder?"file":"page");
        k2printf(" from " TTEXT_BOLD2 "%s" TTEXT_NORMAL " ...\n",filename);
        }
    if (or_detect)
        k2printf("\nDetecting document orientation ... ");
    bormean=1.0;
    for (i=0;1;i+=pagestep)
        {
        char bmpfile[MAXFILENAMELEN];
        int pageno,nextpage;
/*
sprintf(bmpfile,"i=%d",i);
willus_mem_debug_update(bmpfile);
*/
        pageno=0;
        if (pagecount>0 && i+1>pagecount)
            break;
        pageno = double_pagelist_page_by_index(k2settings->pagelist,k2settings->pagexlist,i,np);
        nextpage = (i+2>pagecount) ? -1 : double_pagelist_page_by_index(k2settings->pagelist,
                                                             k2settings->pagexlist,i+1,np);
        /* Removed in v2.32 */
        /* This always returned non-zero */
        /*
        if (!pagelist_page_by_index(k2settings->pagelist,pageno,np))
            continue;
        */
        if (folder)
            {
            if (pageno-1>=fl->n)
                continue;
            wfile_fullname(bmpfile,fl->dir,fl->entry[pageno-1].name);
            status=bmp_read(src,bmpfile,stdout);
            if (status<0)
                {
                if (!second_time_through)
                    k2printf(TTEXT_WARN "\n\aCould not read file %s.\n" TTEXT_NORMAL,bmpfile);
                continue;
                }
            }
        else
            { 
            double npix;

            /* If not a PDF/DJVU/PS file, only read it once. */
            if (i>0 && src_type!=SRC_TYPE_PDF && src_type!=SRC_TYPE_DJVU
                    && src_type!=SRC_TYPE_PS)
                break;

            /* Pre-read at low dpi to check bitmap size */
            wsys_set_decimal_period(1);
            status=bmp_get_one_document_page(src,k2settings,src_type,mupdffilename,pageno,10.,8,
                                             stdout);
            wsys_set_decimal_period(1);
            if (status<0)
                {
                errcnt++;
                if (errcnt<=10)
                    {
                    k2printf(readerr,pageno,filename);
                    if (errcnt==10)
                        k2printf(readlimit,filename);
                    }
                /* Error reading PS probably means we've run out of pages. */
                if (src_type==SRC_TYPE_PS)
                    break;
                continue;
                }

            /* Sanity check the bitmap size */
            npix = (double)(dpi/10.)*(dpi/10.)*src->width*src->height;
            if (npix > 2.5e8 && !pixwarn)
                {
                int ww,hh;
                ww=(int)((double)(dpi/10.)*src->width+.5);
                hh=(int)((double)(dpi/10.)*src->height+.5);
                k2printf("\a\n" TTEXT_WARN "\n\a ** Source resolution is very high (%d x %d pixels)!\n"
                        "    You may want to reduce the -odpi or -idpi setting!\n"
                        "    k2pdfopt may crash when reading the source file..."
                        TTEXT_NORMAL "\n\n",ww,hh);
                pixwarn=1;
                }

            /* Read again at nominal source dpi */
            wsys_set_decimal_period(1);
            if (k2settings_need_color_initially(k2settings))
                status=bmp_get_one_document_page(src,k2settings,src_type,mupdffilename,pageno,
                                                 dpi,24,stdout);
            else
                status=bmp_get_one_document_page(src,k2settings,src_type,mupdffilename,pageno,
                                                 dpi,8,stdout);
            wsys_set_decimal_period(1);
            if (status<0)
                {
                errcnt++;
                if (errcnt<=10)
                    {
                    k2printf(readerr,pageno,filename);
                    if (errcnt==10)
                        aprintf(readlimit,filename);
                    }
                /* Error reading PS probably means we've run out of pages. */
                if (src_type==SRC_TYPE_PS)
                    break;
                continue;
                }
            }
        k2mark_page_count = i+1;

        {
        BMPREGION region;
        int mstatus;

        /* Got Good Page Render */
        bmpregion_init(&region);
        bmpregion_k2pagebreakmarks_allocate(&region);
        mstatus=masterinfo_new_source_page_init(masterinfo,k2settings,src,srcgrey,marked,
                                 &region,rot_deg,&bormean,rotstr,pageno,nextpage,stdout);
        if (mstatus==0)
            {
            /* v2.15 -- memory leak fix */
            bmpregion_free(&region);
            pages_done++;
            continue;
            }
        if (!preview)
            k2printf("\n" TTEXT_HEADER "SOURCE PAGE %d",pageno);
        if (pagecount>0)
            {
            if (!preview)
                {
                if (k2settings->pagelist[0]!='\0')
                    k2printf(" (%d of %d)",pages_done+1,pagecount);
                else
                    k2printf(" of %d",pagecount);
                }
            }
        if (!preview)
            {
            k2printf(TTEXT_NORMAL 
                " (%.1f x %.1f in) ... %s",(double)srcgrey->width/k2settings->src_dpi,
                  (double)srcgrey->height/k2settings->src_dpi,rotstr);
            fflush(stdout);
            }

        /* Parse the source bitmap for viewable regions */
        bmpregion_source_page_add(&region,k2settings,masterinfo,1,pages_done++);
        /* v2.15 memory leak fix */
        bmpregion_free(&region);
        } /* End declaration of BMPREGION region */
#ifdef HAVE_K2GUI
        if (k2gui_active())
            k2gui_cbox_set_pages_completed(pages_done,NULL);
#endif
        if (k2settings->verbose)
            {
            k2printf("    master->rows=%d\n",masterinfo->rows);
            k2printf("Publishing...\n");
            }
        /* Reset the display order for this source page */
        if (k2settings->show_marked_source)
            mark_source_page(k2settings,masterinfo,NULL,0,0xf);
        /*
        ** v2.10 Call masterinfo_publish() no matter what.  If we've just kicked out a
        **       page, it doesn't matter.  It will do nothing.
        */
        masterinfo_publish(masterinfo,k2settings,
                           masterinfo_should_flush(masterinfo,k2settings));
        if (preview && k2_handle_preview(k2settings,masterinfo,k2mark_page_count,
                                         k2settings->dst_color?marked:src,k2out))
            {
            bmp_free(marked);
            bmp_free(srcgrey);
            bmp_free(src);
            masterinfo_free(masterinfo,k2settings);
            if (folder)
                filelist_free(fl);
            k2out->status=0;
            return(0.);
            }
        if (k2settings->show_marked_source && !preview)
            publish_marked_page(mpdf,k2settings->dst_color ? marked : src,k2settings->src_dpi);
        if (!preview)
            {
            int np;
            np=masterinfo->published_pages-pw;
            k2printf("%d new page%s saved.\n",np,np==1?"":"s");
            }
        pw=masterinfo->published_pages;
        }
/*
willus_mem_debug_update("End");
*/
    /* Didn't find the preview page yet--push out final page. */
    if (preview)
        {
        masterinfo_flush(masterinfo,k2settings);
        if (!k2_handle_preview(k2settings,masterinfo,k2mark_page_count,
                               k2settings->dst_color?marked:src,k2out))
            {
            /* No preview bitmap--return zero-width bitmap */
            if (k2out->bmp==NULL)
                bmp_free(masterinfo->preview_bitmap);
            else
                k2out->bmp->width=0;
            }
        bmp_free(marked);
        bmp_free(srcgrey);
        bmp_free(src);
        masterinfo_free(masterinfo,k2settings);
        if (folder)
            filelist_free(fl);
        k2out->status=0;
        return(0.);
        }
    bmp_free(marked);
    bmp_free(srcgrey);
    bmp_free(src);
    /* Determine orientation of document */
    if (or_detect)
        {
        if (pages_done>0)
            {
            double thresh;
            /*
            ** bormean = 1.0 means neutral
            ** bormean >> 1.0 means document is likely portrait (no rotation necessary)
            ** bormean << 1.0 means document is likely landscape (need to rotate it)
            */
            bormean = pow(bormean,1./pages_done);
            thresh=10.-(double)pages_done/2.;
            if (thresh<5.)
                thresh=5.;
            if (bormean < 1./thresh)
                {
                k2printf("Rotating clockwise.\n");
                masterinfo_free(masterinfo,k2settings);
                if (folder)
                    filelist_free(fl);
                k2out->status=0;
                return(270.);
                }
            }
        k2printf("No rotation necessary.\n");
        masterinfo_free(masterinfo,k2settings);
        if (folder)
            filelist_free(fl);
        k2out->status=0;
        return(0.);
        }
    /*
    ** v2.10 -- Calling masterinfo_flush() without checking if a page has just been
    **          been flushed is fine at the end.  If there is nothing left
    **          in the master output bitmap, it won't do anything.
    */
    /*
    if (k2settings->dst_break_pages<=0 && !k2settings_gap_override(k2settings))
    */
        masterinfo_flush(masterinfo,k2settings);
    {
    char cdate[128],author[256],title[256];

#ifdef HAVE_MUPDF_LIB
    if (src_type==SRC_TYPE_PDF)
        {
        if (wmupdf_info_field(mupdffilename,"Author",author,255)<0)
            author[0]='\0';
        if (wmupdf_info_field(mupdffilename,"CreationDate",cdate,127)<0)
            cdate[0]='\0';
        if (wmupdf_info_field(mupdffilename,"Title",title,255)<0)
            title[0]='\0';
        }
    else
#endif
        author[0]=title[0]=cdate[0]='\0';
    if (k2settings->dst_author[0]!='\0')
        strcpy(author,k2settings->dst_author);
    if (k2settings->dst_title[0]!='\0')
        strcpy(title,k2settings->dst_title);
    if (!k2settings->use_crop_boxes)
        {
        if (masterinfo->outline!=NULL)
            {
            if (k2settings->debug)
                wpdfoutline_echo(masterinfo->outline,1,1,stdout);
            pdffile_add_outline(&masterinfo->outfile,masterinfo->outline);
            }
        pdffile_finish(&masterinfo->outfile,title,author,masterinfo->pageinfo.producer,cdate);
        pdffile_close(&masterinfo->outfile);
        }
    else
        {
        /* Re-write PDF file using crop boxes */
#if (WILLUSDEBUGX & 64)
wpdfboxes_echo(&masterinfo->pageinfo.boxes,stdout);
#endif
#ifdef HAVE_MUPDF_LIB
#if (WILLUSDEBUGX & 64)
printf("Calling wpdfpageinfo_scale_source_boxes()...\n");
#endif
        if (k2settings->dst_author[0]!='\0')
            strcpy(masterinfo->pageinfo.author,k2settings->dst_author);
        if (k2settings->dst_title[0]!='\0')
            strcpy(masterinfo->pageinfo.title,k2settings->dst_title);
        /* v2.20 bug fix -- need to compensate for document_scale_factor if its not 1.0 */
        wpdfpageinfo_scale_source_boxes(&masterinfo->pageinfo,1./k2settings->document_scale_factor);
#if (WILLUSDEBUGX & 64)
printf("Calling wmupdf_remake_pdf()...\n");
#endif
        wmupdf_remake_pdf(mupdffilename,dstfile,&masterinfo->pageinfo,1,masterinfo->outline,stdout);
#endif
        }
    if (k2settings->show_marked_source)
        {
        pdffile_finish(mpdf,title,author,masterinfo->pageinfo.producer,cdate);
        pdffile_close(mpdf);
        }
    } // cdate, author, title selection
    if (k2settings->debug || k2settings->verbose)
        k2printf("Cleaning up ...\n\n");
    /*
    if (folder)
        k2printf("Processing on " TTEXT_INPUT "folder %s" TTEXT_NORMAL " complete.  Total %d pages.\n\n",filename,masterinfo->published_pages);
    else
        k2printf("Processing on " TTEXT_BOLD2 "file %s" TTEXT_NORMAL " complete.  Total %d pages.\n\n",filename,masterinfo->published_pages);
    */
    size=wfile_size(dstfile);
    k2printf("\n" TTEXT_BOLD "%d pages" TTEXT_NORMAL,masterinfo->published_pages);
    if (masterinfo->wordcount>0)
        k2printf(" (%d words)",masterinfo->wordcount);
    k2printf(" written to " TTEXT_MAGENTA "%s" TTEXT_NORMAL " (%.1f MB).\n\n",
            dstfile,size/1024./1024.);
#ifdef HAVE_GHOSTSCRIPT
    if (k2settings->ppgs)
        gs_postprocess(dstfile);
#endif
    if (k2settings->show_marked_source)
        {
        size=wfile_size(markedfile);
        k2printf(TTEXT_BOLD "%d pages" TTEXT_NORMAL " written to " TTEXT_MAGENTA "%s" TTEXT_NORMAL " (%.1f MB).\n\n",pages_done,markedfile,size/1024./1024.);
        }
#ifdef HAVE_OCR_LIB
    if (k2settings->dst_ocr && masterinfo->ocrfilename[0]!='\0' && wfile_status(masterinfo->ocrfilename)==1)
        {
        size=wfile_size(masterinfo->ocrfilename);
        k2printf(TTEXT_BOLD "%d words" TTEXT_NORMAL " written to " TTEXT_MAGENTA "%s" TTEXT_NORMAL " (%.1f MB).\n\n",masterinfo->wordcount,masterinfo->ocrfilename,size/1024./1024.);
        }
#endif
    if (local_tocwrites>0)
        k2printf(TTEXT_BOLD "%d bytes" TTEXT_NORMAL " written to " TTEXT_MAGENTA "%s" TTEXT_NORMAL ".\n\n",(int)(wfile_size(k2settings->tocsavefile)+.5),k2settings->tocsavefile);
    masterinfo_free(masterinfo,k2settings);
    if (folder)
        filelist_free(fl);
    k2out->status=0;
    return(0.);
    }
/*
** If arg is a folder, look for files inside of it for PDFs / DJVU files and process
** one by one, otherwise just process the passed argument.
**
** Processing file is two steps:
**     1. If auto-rotation is requested, determine the proper rotation of the file.
**     2. Process the file with the determined rotation.
**
*/
static void k2pdfopt_proc_arg(K2PDFOPT_SETTINGS *k2settings,char *arg,int process,
                              K2PDFOPT_OUTPUT *k2out)

    {
    char filename[MAXFILENAMELEN];
    int i;
    double rot;
    int autorot;

#if (WILLUSDEBUGX & 1)
printf("@k2pdfopt_proc_arg(%s)\n",arg);
printf("wfile_status(%s) = %d\n",arg,wfile_status(arg));
#endif
    strcpy(filename,arg);
    if (wfile_status(filename)==0)
        {
#ifdef HAVE_K2GUI
        if ((!k2gui_active() && process) || (k2gui_active() && !process))
#endif
        k2printf(TTEXT_WARN "\n** File or folder %s could not be opened. **\n\n" TTEXT_NORMAL,filename);
#ifdef HAVE_K2GUI
        if (process && k2gui_active())
            {
            char buf[512];
            k2gui_cbox_increment_error_count();
            sprintf(buf,"File %s cannot be opened.",filename);
            if (k2settings->preview_page>0)
                k2gui_alertbox(0,"File not found",buf);
            else
                k2gui_cbox_set_pages_completed(0,buf);
            }
#endif
        return;
        }
    if (k2settings->info) /* Info only? */
        autorot = 0;
    else if (k2settings->preview_page!=0)
        autorot = (fabs(k2settings->src_rot - SRCROT_AUTOPREV)<.5);
    else
        autorot = (fabs(k2settings->src_rot - SRCROT_AUTOPREV)<.5
                      || fabs(k2settings->src_rot - SRCROT_AUTO)<.5
                      || fabs(k2settings->src_rot - SRCROT_AUTOEP)<.5);
    /* If folder, first process all PDF/DJVU/PS files in the folder */
    if (wfile_status(filename)==2)
        {
        static char *eolist[]={""};
        static char *pdflist[]={"*.pdf","*.djvu","*.djv","*.ps","*.eps",""};
        static char *bmplist[]={"*.png","*.jpg",""};
        FILELIST *fl,_fl;
        FILELIST *fl2,_fl2;
        int nbmp;

        fl=&_fl;
        filelist_init(fl);
        filelist_fill_from_disk(fl,filename,pdflist,eolist,0,0);
        fl2=&_fl2;
        filelist_init(fl2);
        filelist_fill_from_disk(fl2,filename,bmplist,eolist,0,0);
        nbmp=fl2->n;
        filelist_free(fl2);
        if (fl->n>0)
            {
            for (i=0;i<fl->n;i++)
                {
                char fullname[512];

                wfile_fullname(fullname,filename,fl->entry[i].name);
                if (autorot)
                    {
                    if (process)
                        rot=k2pdfopt_proc_one(k2settings,fullname,SRCROT_AUTO,k2out);
                    else
                        rot=0.;
                    }
                else
                    rot=k2settings->src_rot < -990. ? 0. : k2settings->src_rot;
                if (process)
                    k2pdfopt_proc_one(k2settings,fullname,rot,k2out);
                if (!process || k2out->status==0)
                    k2out->filecount++;
#ifdef HAVE_K2GUI
                if (process && k2gui_active())
                    {
                    if (k2out->status!=0)
                        k2gui_cbox_error(filename,k2out->status);
                    else
                        k2gui_cbox_set_files_completed(k2out->filecount,NULL);
                    }
#endif
                }
            }
        filelist_free(fl);
        if (nbmp==0)
            return;
        }
    if (autorot)
        {
        if (process)
            rot=k2pdfopt_proc_one(k2settings,filename,SRCROT_AUTO,k2out);
        else
            rot=0.;
        }
    else
        rot=k2settings->src_rot < -990. ? 0. : k2settings->src_rot;
    if (process)
        k2pdfopt_proc_one(k2settings,filename,rot,k2out);
    if (!process || k2out->status==0)
        k2out->filecount++;
#ifdef HAVE_K2GUI
    if (process && k2gui_active())
        {
        if (k2out->status!=0)
            k2gui_cbox_error(filename,k2out->status);
        else
            k2gui_cbox_set_files_completed(k2out->filecount,NULL);
        }
#endif
    }